【问题标题】:Image optimization like whatsapp and instagram in ios and androidios和android中的whatsapp和instagram等图像优化
【发布时间】:2016-10-19 11:47:17
【问题描述】:

任务:- 像 Facebook 和 WhatApp 一样优化图像? 在android和ios中上传图片到服务器,优化尺寸,不损失图片质量和尺寸。

我见过很多代码,例如原生图像压缩 (UIImageJPEGRepresentation(viewImage, 0.8)),但我无法得到正确的结果。

谁能给我推荐 iOS 和 android 中的任何算法或库,通过它们我们可以优化图像而不会损失质量。

我已经访问过的链接:

iOS

  1. What's the easiest way to resize/optimize an image size with the iPhone SDK?

安卓

  1. https://abdelhady.net/2015/03/28/android-loading-images-super-fast-like-whatsapp-part-2/
  2. https://gist.github.com/vipulasri/0cd97d012934531f1266
  3. http://voidcanvas.com/whatsapp-like-image-compression-in-android/

【问题讨论】:

标签: android ios image bitmap image-optimization


【解决方案1】:

试试这个代码:

+(UIImage *)scaleAndRotateImage:(UIImage *)image {
int kMaxResolution = 640; // Or whatever

CGImageRef imgRef = image.CGImage;

CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);


CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution) {
    CGFloat ratio = width/height;
    if (ratio > 1) {
        bounds.size.width = kMaxResolution;
        bounds.size.height = roundf(bounds.size.width / ratio);
    }
    else {
        bounds.size.height = kMaxResolution;
        bounds.size.width = roundf(bounds.size.height * ratio);
    }
}

CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient) {

    case UIImageOrientationUp: //EXIF = 1
        transform = CGAffineTransformIdentity;
        break;

    case UIImageOrientationUpMirrored: //EXIF = 2
        transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
        break;

    case UIImageOrientationDown: //EXIF = 3
        transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
        transform = CGAffineTransformRotate(transform, M_PI);
        break;

    case UIImageOrientationDownMirrored: //EXIF = 4
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
        transform = CGAffineTransformScale(transform, 1.0, -1.0);
        break;

    case UIImageOrientationLeftMirrored: //EXIF = 5
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
        transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
        break;

    case UIImageOrientationLeft: //EXIF = 6
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
        transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
        break;

    case UIImageOrientationRightMirrored: //EXIF = 7
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeScale(-1.0, 1.0);
        transform = CGAffineTransformRotate(transform, M_PI / 2.0);
        break;

    case UIImageOrientationRight: //EXIF = 8
        boundHeight = bounds.size.height;
        bounds.size.height = bounds.size.width;
        bounds.size.width = boundHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
        transform = CGAffineTransformRotate(transform, M_PI / 2.0);
        break;

    default:
        [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

}

UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();

if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
    CGContextScaleCTM(context, -scaleRatio, scaleRatio);
    CGContextTranslateCTM(context, -height, 0);
}
else {
    CGContextScaleCTM(context, scaleRatio, -scaleRatio);
    CGContextTranslateCTM(context, 0, -height);
}

CGContextConcatCTM(context, transform);

CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGFloat scaleSize = 0.2f;
UIImage *smallImage = [UIImage imageWithCGImage:imageCopy.CGImage
                                          scale:scaleSize
                                    orientation:imageCopy.imageOrientation];

return smallImage;
}

【讨论】:

    【解决方案2】:

    这是我在 Android 中使用的:

    public class ImageCompresser {
    
        public static void compressImage(String inputFilePath, String outputFilePath) {
            try {
    
                final BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
    
                BitmapFactory.decodeFile(inputFilePath, options);
    
                //options.inSampleSize = calculateInSampleSize(options,400,300);
                options.inSampleSize = calculateInSampleSize(options,800,1000);//Specify Minimum Height, Width of the resulting bitmap maintaining the aspect ratio
    
                options.inJustDecodeBounds = false;
    
                Bitmap bm = BitmapFactory.decodeFile(inputFilePath, options);
    
                FileOutputStream fileOutputStream;
    
                fileOutputStream = new FileOutputStream(outputFilePath);
    
                ExifInterface exif;
                try {
                    exif = new ExifInterface(inputFilePath);
    
                    Log.d("EXIF", "Make : " + exif.getAttribute(ExifInterface.TAG_MAKE));
    
                    int orientation = exif.getAttributeInt(
                            ExifInterface.TAG_ORIENTATION, 0);
                    Log.d("EXIF", "Exif Orientation : " + orientation);
                    Matrix matrix = new Matrix();
                    if (orientation == 6) {
                        matrix.postRotate(90);
                        Log.d("EXIF", "Exif: " + orientation);
                    } else if (orientation == 3) {
                        matrix.postRotate(180);
                        Log.d("EXIF", "Exif: " + orientation);
                    } else if (orientation == 8) {
                        matrix.postRotate(270);
                        Log.d("EXIF", "Exif: " + orientation);
                    }
                    Bitmap scaledBitmap = Bitmap.createBitmap(bm, 0, 0,
                            bm.getWidth(), bm.getHeight(), matrix,
                            true);
    
                    scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);//Instead of 100, you can provide any value. But it will reduce the image quality 
                    scaledBitmap.recycle();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                fileOutputStream.flush();
                fileOutputStream.close();
                bm.recycle();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } 
        }
    
        private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
            final int imageWidth = options.outWidth;
            final int imageHeight = options.outHeight;
            Log.d("Test", "imageWidth : " + imageWidth);
            Log.d("Test", "imageHeight : " + imageHeight);
    
            int inSampleSize = 1;
    
            if(imageWidth > reqWidth || imageHeight > reqHeight) {
                final int halfWidth = imageWidth / 2;
                final int halfHeight = imageHeight / 2;
    
                while((halfWidth / inSampleSize) > reqWidth
                        && (halfHeight / inSampleSize) > reqHeight) {
                    inSampleSize *= 2;
                }
            }
    
            return inSampleSize;
        }
    }
    

    参考文献:

    1. http://voidcanvas.com/whatsapp-like-image-compression-in-android/
    2. https://developer.android.com/training/displaying-bitmaps/load-bitmap.html

    【讨论】:

      猜你喜欢
      • 2014-10-05
      • 1970-01-01
      • 2013-12-29
      • 1970-01-01
      • 2013-01-12
      • 2014-06-20
      • 2016-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多