android上傳圖片壓縮圖片大小

來源:互聯網
上載者:User

現在手機拍照都是好幾兆,直接把原圖上傳到伺服器,對於使用者來說,直接就崩潰了,在有WiFi的情況下還好。但當其他使用者查看列表時,看一會估計手機都得欠費了。所以在上傳圖片的時候,要對圖片進行壓縮。
注意:這裡的壓縮是指品質壓縮,不是尺寸壓縮。

比如當我們拍一張照片,要上傳到伺服器。我們需要先把這個照片,讀到記憶體中,然後進行壓縮,最後把壓縮後的檔案輸出。

關於圖片的記憶體了,怎麼載入節省記憶體了,這裡就不說了
推薦讀者看看這篇文章:http://www.jcodecraeer.com/plus/view.php?aid=3874

以下代碼來自ImageLoader架構,我把它decoder圖片的代碼抽了出來,稍作了一下修改

使用代碼

public class MainActivity extends AppCompatActivity {    String imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "123.jpg";    String outPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "new.jpg";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        final ImageDecoder decoder = new ImageDecoder();        final ImageSize imageSize = new ImageSize(400, 800);        final File file = new File(imagePath);        if (file.exists()) {            new Thread() {                @Override                public void run() {                    super.run();                    try {                        Bitmap bitmap = decoder.decode(file, imageSize);                        ImageUtils.compressBmpToFile(bitmap, new File(outPath));                    } catch (IOException e) {                        e.printStackTrace();                    }                }            }.start();        }    }}

ImageDecoder 類負責把圖片decode成目標大小,然後ImageUtils.compressBmpToFile對圖片進行壓縮,壓縮完之後(壓縮到100K以內),輸出檔案

ImageDecoder.java

public class ImageDecoder {    public Bitmap decode(File file, ImageSize targetSize) throws IOException {        Bitmap decodedBitmap;        ImageFileInfo imageInfo;        InputStream imageStream = getImageStream(file);        try {            imageInfo = defineImageSizeAndRotation(imageStream, file);            imageStream = resetStream(imageStream, file);            BitmapFactory.Options decodingOptions = prepareDecodingOptions(imageInfo.imageSize, targetSize);            decodedBitmap = BitmapFactory.decodeStream(imageStream, null, decodingOptions);        } finally {            closeSilently(imageStream);        }        if (decodedBitmap != null) {            decodedBitmap = considerExactScaleAndOrientatiton(decodedBitmap, targetSize, imageInfo.exif.rotation,                    imageInfo.exif.flipHorizontal);        }        return decodedBitmap;    }    private InputStream getImageStream(File res) throws IOException{        return new FileInputStream(res);    }    /**     * 定義image的大小和旋轉的度     */    protected ImageFileInfo defineImageSizeAndRotation(InputStream imageStream, File file)            throws IOException {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeStream(imageStream, null, options);        ExifInfo exif;        if (canDefineExifParams(options.outMimeType)) {            exif = defineExifOrientation(file);        } else {            exif = new ExifInfo();        }        return new ImageFileInfo(new ImageSize(options.outWidth, options.outHeight, exif.rotation), exif);    }    private boolean canDefineExifParams(String mimeType) {        return "image/jpeg".equalsIgnoreCase(mimeType);    }    protected ExifInfo defineExifOrientation(File imageUri) {        int rotation = 0;        boolean flip = false;        try {            ExifInterface exif = new ExifInterface(imageUri.getAbsolutePath());            int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);            switch (exifOrientation) {                case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:                    flip = true;                case ExifInterface.ORIENTATION_NORMAL:                    rotation = 0;                    break;                case ExifInterface.ORIENTATION_TRANSVERSE:                    flip = true;                case ExifInterface.ORIENTATION_ROTATE_90:                    rotation = 90;                    break;                case ExifInterface.ORIENTATION_FLIP_VERTICAL:                    flip = true;                case ExifInterface.ORIENTATION_ROTATE_180:                    rotation = 180;                    break;                case ExifInterface.ORIENTATION_TRANSPOSE:                    flip = true;                case ExifInterface.ORIENTATION_ROTATE_270:                    rotation = 270;                    break;            }        } catch (IOException e) {            Log.w("decoder", "Can't read EXIF tags from file [%s]" + imageUri.getAbsolutePath());        }        return new ExifInfo(rotation, flip);    }    /**     * 如果imageStream支援reset,則返回reset後的imageStream,否則返回 {@link #getImageStream(File)}     */    protected InputStream resetStream(InputStream imageStream, File res) throws IOException {        //http://zhangbo-peipei-163-com.iteye.com/blog/2022460        if (imageStream.markSupported()) {            try {                imageStream.reset();                return imageStream;            } catch (IOException ignored) {            }        }        closeSilently(imageStream);        return getImageStream(res);    }    /**     * 返回計算好 simple size 的Option     */    protected BitmapFactory.Options prepareDecodingOptions(ImageSize imageSize, ImageSize targetSize) {        int scale = ImageUtils.computeImageSampleSize(imageSize, targetSize);        BitmapFactory.Options decodingOptions = new BitmapFactory.Options();        decodingOptions.inSampleSize = scale;        return decodingOptions;    }    protected Bitmap considerExactScaleAndOrientatiton(Bitmap subsampledBitmap, ImageSize targetSize,                                                       int rotation, boolean flipHorizontal) {        Matrix m = new Matrix();        // 縮小到精確的大小,如果需要        ImageSize srcSize = new ImageSize(subsampledBitmap.getWidth(), subsampledBitmap.getHeight(), rotation);        float scale = ImageUtils.computeImageScale(srcSize, targetSize, false);        if (Float.compare(scale, 1f) != 0) {            m.setScale(scale, scale);        }        // 翻轉 bitmap 如果需要        if (flipHorizontal) {            m.postScale(-1, 1);        }        // 選擇 bitmap 如果需要        if (rotation != 0) {            m.postRotate(rotation);        }        Bitmap finalBitmap = Bitmap.createBitmap(subsampledBitmap, 0, 0, subsampledBitmap.getWidth(), subsampledBitmap                .getHeight(), m, true);        if (finalBitmap != subsampledBitmap) {            subsampledBitmap.recycle();        }        return finalBitmap;    }    protected static class ExifInfo {        public final int rotation;        public final boolean flipHorizontal;        protected ExifInfo() {            this.rotation = 0;            this.flipHorizontal = false;        }        protected ExifInfo(int rotation, boolean flipHorizontal) {            this.rotation = rotation;            this.flipHorizontal = flipHorizontal;        }    }    protected static class ImageFileInfo {        public final ImageSize imageSize;        public final ExifInfo exif;        protected ImageFileInfo(ImageSize imageSize, ExifInfo exif) {            this.imageSize = imageSize;            this.exif = exif;        }    }    public static void closeSilently(Closeable closeable) {        if (closeable != null) {            try {                closeable.close();            } catch (Exception ignored) {            }        }    }}

ImageUtils .java

public class ImageUtils {    private static final int DEFAULT_MAX_BITMAP_DIMENSION = 2048;    private static ImageSize maxBitmapSize;    static {        int[] maxTextureSize = new int[1];        GLES10.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);        int maxBitmapDimension = Math.max(maxTextureSize[0], DEFAULT_MAX_BITMAP_DIMENSION);        maxBitmapSize = new ImageSize(maxBitmapDimension, maxBitmapDimension);    }    private ImageUtils() {    }    public static int computeImageSampleSize(ImageSize srcSize, ImageSize targetSize){        final int srcWidth = srcSize.getWidth();        final int srcHeight = srcSize.getHeight();        final int targetWidth = targetSize.getWidth();        final int targetHeight = targetSize.getHeight();        int scale = 1;        scale = Math.min(srcWidth / targetWidth, srcHeight / targetHeight); // min        if (scale < 1) {            scale = 1;        }        scale = considerMaxTextureSize(srcWidth, srcHeight, scale, false);        return scale;    }    /**     * 如果寬度和高度/scale大於max texture size則繼續縮小     * @return sample size     */    private static int considerMaxTextureSize(int srcWidth, int srcHeight, int scale, boolean powerOf2) {        final int maxWidth = maxBitmapSize.getWidth();        final int maxHeight = maxBitmapSize.getHeight();        while ((srcWidth / scale) > maxWidth || (srcHeight / scale) > maxHeight) {            if (powerOf2) {                scale *= 2;            } else {                scale++;            }        }        return scale;    }    public static float computeImageScale(ImageSize srcSize, ImageSize targetSize,                                          boolean stretch) {        final int srcWidth = srcSize.getWidth();        final int srcHeight = srcSize.getHeight();        final int targetWidth = targetSize.getWidth();        final int targetHeight = targetSize.getHeight();        final float widthScale = (float) srcWidth / targetWidth;        final float heightScale = (float) srcHeight / targetHeight;        final int destWidth;        final int destHeight;        if (widthScale < heightScale) {            destWidth = targetWidth;            destHeight = (int) (srcHeight / widthScale);        } else {            destWidth = (int) (srcWidth / heightScale);            destHeight = targetHeight;        }        float scale = 1;        if ((!stretch && destWidth < srcWidth && destHeight < srcHeight) || (stretch && destWidth != srcWidth && destHeight != srcHeight)) {            scale = (float) destWidth / srcWidth;        }        return scale;    }    public static void compressBmpToFile(Bitmap bmp, File file) {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        int options = 80;        bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);        while (baos.toByteArray().length / 1024 > 100) {            options -= 10;            if (options > 0) {                baos.reset();                bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);            } else {                break;            }        }        try {            FileOutputStream fos = new FileOutputStream(file);            byte[] bytes = baos.toByteArray();            fos.write(bytes);            fos.flush();            fos.close();            Log.i("tag", "file.length" + file.length());        } catch (Exception e) {            e.printStackTrace();        }    }}

ImageSize.java

public class ImageSize {    private final int width;    private final int height;    public ImageSize(int width, int height) {        this.width = width;        this.height = height;    }    public ImageSize(int width, int height, int rotation) {        if (rotation % 180 == 0) {            this.width = width;            this.height = height;        } else {            this.width = height;            this.height = width;        }    }    public int getWidth() {        return width;    }    public int getHeight() {        return height;    }}

github地址
https://github.com/wu-liao-de-ren-sheng/ImageCompress

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.