UIImage를 축소하고 흐릿하게 만드는 대신 동시에 파삭 파삭하고 선명하게 만드는 방법은 무엇입니까?
이미지의 크기를 줄여야하지만 선명하게해야합니다. 예를 들어 Photoshop에는 이미지 크기 축소 옵션 "Bicubic Smoother"(흐리게) 및 "Bicubic Sharper"가 있습니다.
이 이미지 축소 알고리즘이 오픈 소스이거나 어딘가에 문서화되어 있습니까? 아니면 SDK가이를 수행하는 방법을 제공합니까?
단순히 사용하는 것만으로 imageWithCGImage
는 충분하지 않습니다. 확장되지만 결과는 확대 또는 축소 여부에 관계없이 흐릿하고 차선책입니다.
앨리어싱을 올바르게하고 "재기"를 제거하려면 다음과 같은 것이 필요합니다. http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right- 방법 / .
내 작업 테스트 코드는 다음과 같이 보입니다. 투명한 PNG로 작업하기 위해 약간의 조정이있는 Trevor의 솔루션입니다.
- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = image.CGImage;
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);
CGContextConcatCTM(context, flipVertical);
// Draw into the context; this scales the image
CGContextDrawImage(context, newRect, imageRef);
// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
CGImageRelease(newImageRef);
UIGraphicsEndImageContext();
return newImage;
}
Swift를 사용하는 사람들에게는 Swift에서 허용되는 답변이 있습니다.
func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {
let newRect = CGRectIntegral(CGRectMake(0,0, newSize.width, newSize.height))
let imageRef = image.CGImage
UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
let context = UIGraphicsGetCurrentContext()
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(context, kCGInterpolationHigh)
let flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height)
CGContextConcatCTM(context, flipVertical)
// Draw into the context; this scales the image
CGContextDrawImage(context, newRect, imageRef)
let newImageRef = CGBitmapContextCreateImage(context) as CGImage
let newImage = UIImage(CGImage: newImageRef)
// Get the resized image from the context and a UIImage
UIGraphicsEndImageContext()
return newImage
}
누군가 Swift 버전을 찾고 있다면 @Dan Rosenstark의 수락 된 답변의 Swift 버전은 다음과 같습니다.
func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage {
let scale = newHeight / image.size.height
let newWidth = image.size.width * scale
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
크기를 조정하는 동안 이미지의 원래 종횡비를 유지하면 아무리 축소해도 항상 선명한 이미지가됩니다.
다음 방법을 사용하여 확장 할 수 있습니다.
+ (UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
Swift 3의 경우
func resizeImage(image: UIImage, newSize: CGSize) -> (UIImage) {
let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral
UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
let context = UIGraphicsGetCurrentContext()
// Set the quality level to use when rescaling
context!.interpolationQuality = CGInterpolationQuality.default
let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height)
context!.concatenate(flipVertical)
// Draw into the context; this scales the image
context?.draw(image.cgImage!, in: CGRect(x: 0.0,y: 0.0, width: newRect.width, height: newRect.height))
let newImageRef = context!.makeImage()! as CGImage
let newImage = UIImage(cgImage: newImageRef)
// Get the resized image from the context and a UIImage
UIGraphicsEndImageContext()
return newImage
}
@YAR 솔루션이 제대로 작동하고 있습니다.
내 요구 사항에 맞지 않는 한 가지가 있습니다. 전체 이미지의 크기가 조정됩니다. 나는 photos app on iphone
. 이것은 "긴면"을 계산하고 "오버레이"를 잘라내어 이미지 품질과 관련하여 훨씬 더 나은 결과를 얻습니다.
- (UIImage *)resizeImageProportionallyIntoNewSize:(CGSize)newSize;
{
CGFloat scaleWidth = 1.0f;
CGFloat scaleHeight = 1.0f;
if (CGSizeEqualToSize(self.size, newSize) == NO) {
//calculate "the longer side"
if(self.size.width > self.size.height) {
scaleWidth = self.size.width / self.size.height;
} else {
scaleHeight = self.size.height / self.size.width;
}
}
//prepare source and target image
UIImage *sourceImage = self;
UIImage *newImage = nil;
// Now we create a context in newSize and draw the image out of the bounds of the context to get
// A proportionally scaled image by cutting of the image overlay
UIGraphicsBeginImageContext(newSize);
//Center image point so that on each egde is a little cutoff
CGRect thumbnailRect = CGRectZero;
thumbnailRect.size.width = newSize.width * scaleWidth;
thumbnailRect.size.height = newSize.height * scaleHeight;
thumbnailRect.origin.x = (int) (newSize.width - thumbnailRect.size.width) * 0.5;
thumbnailRect.origin.y = (int) (newSize.height - thumbnailRect.size.height) * 0.5;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(@"could not scale image");
return newImage ;
}
This extension should scale the image while keeping original aspect ratio. The rest of the image is cropped. (Swift 3)
extension UIImage {
func thumbnail(ofSize proposedSize: CGSize) -> UIImage? {
let scale = min(size.width/proposedSize.width, size.height/proposedSize.height)
let newSize = CGSize(width: size.width/scale, height: size.height/scale)
let newOrigin = CGPoint(x: (proposedSize.width - newSize.width)/2, y: (proposedSize.height - newSize.height)/2)
let thumbRect = CGRect(origin: newOrigin, size: newSize).integral
UIGraphicsBeginImageContextWithOptions(proposedSize, false, 0)
draw(in: thumbRect)
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
For swift 4.2:
extension UIImage {
func resized(By coefficient:CGFloat) -> UIImage? {
guard coefficient >= 0 && coefficient <= 1 else {
print("The coefficient must be a floating point number between 0 and 1")
return nil
}
let newWidth = size.width * coefficient
let newHeight = size.height * coefficient
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
'Development Tip' 카테고리의 다른 글
Git 로그에 오늘의 모든 커밋을 표시하는 방법은 무엇입니까? (0) | 2020.10.20 |
---|---|
s3cmd를 사용하여 한 S3 버킷에서 다른 버킷으로 모든 파일을 복사 할 수 있습니까? (0) | 2020.10.20 |
클래스 변수 인 클로저를 호출하는 방법은 무엇입니까? (0) | 2020.10.20 |
실행 시간이없는 루프 (0) | 2020.10.20 |
페이드 인 및 추가 사용 (0) | 2020.10.20 |