2016-08-12 5 views
1

온라인에서 모든 스택 오버플로 게시물 및 비디오를 조사 해본 결과 제대로 작동하는 솔루션을 찾을 수 없습니다. 현재 사용자는 AWS S3 버킷에 업로드하기 전에 압축 할 사진을 선택합니다. 업로드가 완벽하게 작동하지만 압축 된 이미지가 원래 이미지보다 큽니다. 예를 들어 사용자가 9KB 사진을 선택하면 S3에 업로드 할 때 사진은 28.5KB입니다. 나는 다른 사진을 시도했고 그것은 48KB이고 S3의 "압축"후에는 378.9KB! (모든 최신 소프트웨어 버전을 사용하고 시뮬레이터로 컴파일 중입니다.)iOS에서 이미지를 압축하는 방법?

업로드하기 전에 최대한 원본 이미지를 압축하고 싶습니다.

내가 이미지를 "압축"방법 :

내가 지금까지 무엇을 가지고

//Convert product UIImage 
NSArray *productImagePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *productImageFilePath = [[productImagePaths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@".png"]]; 
[UIImagePNGRepresentation(compressedProductImage) writeToFile:productImageFilePath atomically:YES]; 
NSURL *productImageFileUrl = [NSURL fileURLWithPath:productImageFilePath]; 

uploadRequest.body = productImageFileUrl;//Needs to be a NSURL 
uploadRequest.bucket = AWS_BUCKET_NAME; 
uploadRequest.key = productImageKey; 
uploadRequest.contentType = @"image/png"; 
uploadRequest.ACL = AWSS3BucketCannedACLPublicRead; 

[[transferManager upload:uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor] withBlock:^id(AWSTask *task) { 
    if (task.error != nil) { 
     NSLog(@"%s %@","Error uploading (product image):", uploadRequest.key); 
    }else{ 
     NSLog(@"Product image upload completed"); 
    } 
    return nil; 
}]; 

답변

3

당신 돈 : 나는 사진을 업로드하는 방법

UIImage *compressedProductImage; 
NSData *NSproductImage; 
NSUInteger productImageSize; 

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{ 
    self.productImage = info[UIImagePickerControllerOriginalImage]; 
    [self.productImageImageView setImage:self.productImage]; 
    [self dismissViewControllerAnimated:YES completion:nil]; 

    NSproductImage = UIImageJPEGRepresentation(self.productImage, 0.5f); 
    productImageSize = [NSproductImage length]; 

    compressedProductImage = [UIImage imageWithData: NSproductImage]; 

실제로 아무것도 압축하지 않습니다. UIImage으로 시작하십시오. 이것은 (전형적으로) 폭 x 높이 x 4 바이트를 차지하는 완전한 픽셀 별 픽셀 표현입니다.

그런 다음 압축하여 JPG로 변환합니다. 따라서 NSproductImage은 이미지의 JPG 버전을 메모리에서 훨씬 더 작게 표현합니다. 이것은 현재 압축 된 것으로 생각되는 작은 크기라고 가정합니다.

그런 다음 UIImage으로 다시 그 JPG 데이터를 변환합니다. compressedProductImage. 이 새로운 UIImage은 원래 너비가 동일하고 높이가 원래 UIImage입니다. 결과적으로 원본과 동일한 너비 x 높이 x 4 바이트를 사용합니다. JPG 압축으로 인해 원본보다 품질이 낮습니다.

이제 업데이트 된 UIImage을 PNG로 변환합니다. PNG는 무손실이기 때문에 JPG 시도만큼 압축하지 않습니다. 그런 다음 이미지의이 더 큰 PNG 버전을 Amazon으로 보냅니다.

먼저 JPG로 변환 한 다음 다시 UIImage으로 되돌아 오는 무의미한 코드를 제거해야합니다.

이 시점에서 PNG 크기로 살거 나 대신 JPG를 사용하고 작은 JPG를 Amazon으로 보내야합니다.

다른 옵션은 이미지를 Amazon으로 보내기 전에 크기를 조정하는 것입니다.

+0

그래서 그것은 모든 업로드하기 전에 이미지를 압축 복잡하거나하지 가치에 하나처럼 보인다. 나는 더 큰 이미지를 다루고 더 나은 캐싱 시스템에서 작업 할 것이라고 생각합니다. 통찰력있는 응답에 감사드립니다! –

3

rmaddy가 지적한 것처럼 선택한 이미지를 JPEG로 변환하고 다시 UIImage (JPEG 압축의 이점을 잃어 버림)으로 변환 한 다음 적당한 압축을 제공하는 PNG로 변환합니다. 일반적으로 사용자 사진 라이브러리의 원본 JPEG보다 압축률이 훨씬 낮습니다.

몇 가지 옵션이 있습니다. 이에 방지 https://stackoverflow.com/a/32845656/1271826 같이

  1. 당신은 당신의 사진 라이브러리에 자산의 원래 imageData를 검색 할 수 전혀 UIImage를 통해 라운드 트립. 따라서 원본 이미지의 품질을 유지하고이 이미지와 관련된 메타 데이터를 보존하며 원본 애셋을 적절히 압축 할 수 있습니다.(샘플 알고리즘 https://stackoverflow.com/a/10491692/1271826를 참조) UIImageJPEGRepresentation를 호출하기 전에 이미지의 크기를 줄일

    • ;

    • 당신은 UIImage로 포착 된 이미지를 가지고 조합을 할 수 및/또는

    • 품질이 1.0보다 작은 경우, 숫자가 작을수록 압축은 많지만 화질 손실은 더 커집니다.

+0

그래서 업로드하기 전에 이미지를 압축하는 것은 복잡하거나 가치가없는 것처럼 보입니다. 나는 더 큰 이미지를 다루고 더 나은 캐싱 시스템에서 작업 할 것이라고 생각합니다. 통찰력있는 응답에 감사드립니다! –

+0

너무 복잡해서 무슨 뜻인지 모르겠습니다. 'didFinishPickingMediaWithInfo'가 호출되면,'UIImagePickerControllerReferenceURL'을 잡고,'PHImageManager'에서 원래의 애셋을 가져 와서 보냅니다. 그것은 아주 간단합니다. 원본 애셋을 얻으실 수 있습니다. 작고 멋지 며 이미지 품질이나 메타 데이터 손실이 없으며 복잡한 모든 JPEG 변환 및 PNG 로의 변환을 피할 수 있습니다. 그러나 각자 자신에게. – Rob

관련 문제