그림 압축 방법
이미지 품질 압축(quality), 이미지 크기 압축(size)
압축 이미지 품질
NSData *data = UIImageJPEGRepresentation(image, compression);
UIImage *resultImage = [UIImage imageWithData:data];
또는
NSData *data = UIImagePNGRepresentation(UIImage * __nonnull image);
UIImage *resultImage = [UIImage imageWithData:data];
전자는 압축 비율을 조절할 수 있고 후자가 차지하는 바이트보다 적기 때문에 그림의 질에 대한 요구가 비교적 높지 않으면 보통 JPEG의 압축 방식을 사용한다.
압축 이미지 크기
UIGraphicsBeginImageContext(targetSize);
[image drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
필요한 그림 크기를 targetsize로 지정하면,resultImage는 원래 그림의 이미지를 targetsize 크기로 그립니다.
그림을 압축해서 그림 파일을 지정한 크기보다 작게 합니다
만약에 사진의 선명도에 대한 요구가 높지 않고 사진의 업로드, 다운로드 속도가 빨라야 한다면 사진을 업로드하기 전에 사진을 압축해야 한다.어느 정도로 압축하는지는 구체적인 상황을 보아야 하지만, 일반적으로 그림 파일의 최대 값을 설정한다. 예를 들어 100KB이다.상술한 두 가지 방법을 채택하여 그림을 압축할 수 있다.그림이 변환된 NSData 대상이 데이터라고 가정하면 4
data.length
그림의 바이트 크기를 얻을 수 있다.압축 이미지 품질
비교적 쉽게 생각할 수 있는 방법은 그림이 지정한 크기(maxLength)보다 조금 작을 때까지 순환을 통해 그림의 질을 점차적으로 줄이는 것이다.
+ (UIImage *)compressImageQuality:(UIImage *)image toByte:(NSInteger)maxLength {
CGFloat compression = 1;
NSData *data = UIImageJPEGRepresentation(image, compression);
while (data.length > maxLength && compression > 0) {
compression -= 0.02;
data = UIImageJPEGRepresentation(image, compression); // When compression less than a value, this code dose not work
}
UIImage *resultImage = [UIImage imageWithData:data];
return resultImage
이렇게 순환하는 횟수가 많고 효율이 낮으며 시간이 오래 걸린다.이분법을 통해 최적화할 수 있다.
+ (UIImage *)compressImageQuality:(UIImage *)image toByte:(NSInteger)maxLength {
CGFloat compression = 1;
NSData *data = UIImageJPEGRepresentation(image, compression);
if (data.length < maxLength) return image;
CGFloat max = 1;
CGFloat min = 0;
for (int i = 0; i < 6; ++i) {
compression = (max + min) / 2;
data = UIImageJPEGRepresentation(image, compression);
if (data.length < maxLength * 0.9) {
min = compression;
} else if (data.length > maxLength) {
max = compression;
} else {
break;
}
}
UIImage *resultImage = [UIImage imageWithData:data];
return resultImage;
}
그림 크기가 maxLength 보다 작고 maxlength * 0.9 보다 크면 더 이상 압축하지 않습니다.최대 6회, 1/(2^6)= 0.015625 <0.02도 순환마다compression이 0.02를 줄이는 효과에 도달할 수 있다.이런 압축 횟수는 순환 감소compression보다 적고 소모 시간이 짧다.주의해야 할 것은 그림의 질이 어느 정도 낮을 때 계속 압축하면 효과가 없다는 것이다.즉, compression은 계속 줄어들고 데이터도 더 이상 줄어들지 않는다는 것이다.
압축 그림의 품질의 장점은 가능한 한 그림의 선명도를 보존하고 그림이 뚜렷하게 모호하지 않다는 데 있다.단점은 그림이 압축된 후 지정된 크기보다 작다는 것을 보장할 수 없다는 것이다.
압축 이미지 크기
이전과 유사하게 비교적 쉽게 생각할 수 있는 방법은 그림의 크기를 지정한 크기(maxLength)보다 조금 작을 때까지 순환을 통해 점차적으로 줄이는 것이다.구체적인 코드가 생략되다.같은 문제는 순환 횟수가 많고 효율이 낮으며 시간이 오래 걸린다는 것이다.이분법으로 효율을 높일 수 있으며 구체적인 코드는 생략할 수 있다.이분법보다 더 좋고 압축 횟수가 적으며 그림을 압축한 후 지정한 크기보다 꼭 작게 할 수 있는 또 다른 방법을 소개한다(
+ (UIImage *)compressImageSize:(UIImage *)image toByte:(NSUInteger)maxLength {
UIImage *resultImage = image;
NSData *data = UIImageJPEGRepresentation(resultImage, 1);
NSUInteger lastDataLength = 0;
while (data.length > maxLength && data.length != lastDataLength) {
lastDataLength = data.length;
CGFloat ratio = (CGFloat)maxLength / data.length;
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
(NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
UIGraphicsBeginImageContext(size);
// Use image to draw (drawInRect:), image is larger but more compression time
// Use result image to draw, image is smaller but less compression time
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
data = UIImageJPEGRepresentation(resultImage, 1);
}
return resultImage;
}
그림의 크기를 압축하면 그림이 지정한 크기보다 작지만 그림이 뚜렷하게 모호해진다. (압축된 그림보다 질이 모호하다.)
두 가지 사진 압축 방법이 결합되다
만약 그림의 선명도를 확보하려면 그림의 질을 압축하는 것을 선택하는 것을 권장한다.만약 그림이 반드시 지정된 크기보다 작게 하려면, 그림의 크기를 압축하면 만족할 수 있다.이후의 수요에 따라 먼저 그림의 질을 압축할 수 있다. 만약에 지정한 크기보다 작으면 뚜렷한 그림을 얻을 수 있고 그렇지 않으면 그림의 사이즈를 압축할 수 있다.
+ (UIImage *)compressImage:(UIImage *)image toByte:(NSUInteger)maxLength {
// Compress by quality
CGFloat compression = 1;
NSData *data = UIImageJPEGRepresentation(image, compression);
if (data.length < maxLength) return image;
CGFloat max = 1;
CGFloat min = 0;
for (int i = 0; i < 6; ++i) {
compression = (max + min) / 2;
data = UIImageJPEGRepresentation(image, compression);
if (data.length < maxLength * 0.9) {
min = compression;
} else if (data.length > maxLength) {
max = compression;
} else {
break;
}
}
UIImage *resultImage = [UIImage imageWithData:data];
if (data.length < maxLength) return resultImage;
// Compress by size
NSUInteger lastDataLength = 0;
while (data.length > maxLength && data.length != lastDataLength) {
lastDataLength = data.length;
CGFloat ratio = (CGFloat)maxLength / data.length;
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
(NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
UIGraphicsBeginImageContext(size);
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
data = UIImageJPEGRepresentation(resultImage, compression);
}
return resultImage;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.