web-dev-qa-db-ja.com

画像を圧縮してファイルサイズを縮小

ユーザーが写真を撮るか、iPhoneのライブラリから写真を選択して、Parseバックエンドにアップロードできるアプリを作成しています。

私が直面している問題は、ファイルのサイズに関するものです。

Facebook、Twitter、Instagram、Googleなどの大手企業が解像度とファイルサイズに関して何をしているのかを読んだことがありますが、それに近づくことはできません。

彼らはそれを行うための最高のコードとツールを持っていると確信していますが、iOSの通常のプロセスで可能な限りうまく実装できることを嬉しく思います。

これは私が今していることです:

- (UIImage *)normalResImageForAsset:(ALAsset*)asset
{
    // Convert ALAsset to UIImage
    UIImage *image = [self highResImageForAsset:asset];

    // Determine output size
    CGFloat maxSize = 1024.0f;
    CGFloat width = image.size.width;
    CGFloat height = image.size.height;
    CGFloat newWidth = width;
    CGFloat newHeight = height;

    // If any side exceeds the maximun size, reduce the greater side to 1200px and proportionately the other one
    if (width > maxSize || height > maxSize) {
        if (width > height) {
            newWidth = maxSize;
            newHeight = (height*maxSize)/width;
        } else {
            newHeight = maxSize;
            newWidth = (width*maxSize)/height;
        }
    }

    // Resize the image
    CGSize newSize = CGSizeMake(newWidth, newHeight);
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Set maximun compression in order to decrease file size and enable faster uploads & downloads
    NSData *imageData = UIImageJPEGRepresentation(newImage, 0.0f);
    UIImage *processedImage = [UIImage imageWithData:imageData];

    return processedImage;
}

1024pxを最大許容サイズ(両方とも高さ)にして、そこでいくつかの制限を開始しようとしています。次に、最大圧縮を適用してサイズを縮小しています。

これは機能し、JPEGに実際に損傷を与えることなく、画像サイズの約50%をカットしますが、それでもまだたくさんあります。特に写真が携帯電話のカメラで撮影され、アップロードされた場合。処理された画像はまだ簡単に1MBのサイズになる可能性があります。

私はいくつかの有用なステップを逃したり、間違ったテクニックを使用したりする可能性があると推測しています。

フィードバックをいただければ幸いです。

9
Juan González

同様の問題があり、圧縮が機能していないと思いました。コードの他の場所で、別の圧縮を使用してファイルをディスクに書き込んでいたことが判明しました。この関数が返すデータで同じことをしている可能性があります。実際に圧縮が効果的であることを確認する良い方法は、次のようなことを行うことです。

NSData *imgData1 = UIImageJPEGRepresentation(newImage, 1.0f);
NSLog(@"1.0 size: %d", imgData1.length);

NSData *imgData2 = UIImageJPEGRepresentation(newImage, 0.7f);
NSLog(@"0.7 size: %d", imgData2.length);

NSData *imgData3 = UIImageJPEGRepresentation(newImage, 0.4f);
NSLog(@"0.4 size: %d", imgData3.length);

NSData *imgData4 = UIImageJPEGRepresentation(newImage, 0.0f);
NSLog(@"0.0 size: %d", imgData4.length);

// Don't convert NSData back to UIImage before writing to disk
[imgData4 writeToFile:imagePath atomically:YES];

640x480の画像を使用しており、ファイルサイズは325 kB(1.0の場合)から18 kB(0.0の場合)の範囲です。

9
codemonkey
Please Try below answer.

+(UIImage *)compressImage:(UIImage *)image{
float actualHeight = image.size.height;
float actualWidth = image.size.width;
float maxHeight = 1136.0f;
float maxWidth = 640.0f;
float imgRatio = actualWidth/actualHeight;
float maxRatio = maxWidth/maxHeight;
float compressionQuality = 1;//50 percent compression

if (actualHeight > maxHeight || actualWidth > maxWidth){
    if(imgRatio < maxRatio){
        //adjust width according to maxHeight
        imgRatio = maxHeight / actualHeight;
        actualWidth = imgRatio * actualWidth;
        actualHeight = maxHeight;
    }
    else if(imgRatio > maxRatio){
        //adjust height according to maxWidth
        imgRatio = maxWidth / actualWidth;
        actualHeight = imgRatio * actualHeight;
        actualWidth = maxWidth;
    }
    else{
        actualHeight = maxHeight;
        actualWidth = maxWidth;
    }
}else{
    actualHeight = maxHeight;
    actualWidth = maxWidth;
    compressionQuality = 1;
}

CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
NSData *imageData = UIImageJPEGRepresentation(img, compressionQuality);
UIGraphicsEndImageContext();

return [UIImage imageWithData:imageData];
}
0
herry.master

Swift-3バージョンの@codeMonkey:-

画像の圧縮でperfect動作します。

func compressImage() -> UIImage {

        let oldImage = UIImage(named: "background.jpg")
        var imageData =  Data(UIImagePNGRepresentation(oldImage!)! )
        print("***** Uncompressed Size \(imageData.description) **** ")

        imageData = UIImageJPEGRepresentation(oldImage!, 0.025)!
        print("***** Compressed Size \(imageData.description) **** ")

        let image = UIImage(data: imageData)
        return image!

    }

enter image description here

0
Shrawan