Android图片压缩、加水印

指定图片文件大小压缩

实现

public Bitmap compressAndGenImage(Bitmap image, String outPath, int maxSize)
            throws IOException {
        Bitmap bitmap;
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // scale
        int options = 100;
        // Store the bitmap into output stream(no compress)
        image.compress(Bitmap.CompressFormat.JPEG, options, os);
        // Compress by loop
        while (os.toByteArray().length / 1024 > maxSize) {
            // Clean up os
            os.reset();
            // 每次质量下降10
            options -= 10;
            image.compress(Bitmap.CompressFormat.JPEG, options, os);
        }
        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
        bitmap = BitmapFactory.decodeStream(is);
        // Generate compressed image file
        FileOutputStream fos = new FileOutputStream(outPath);
        fos.write(os.toByteArray());
        fos.flush();
        fos.close();
        is.close();
        return bitmap;
    }

优点

这种方式压缩得图片,可以减少文件的存储体积,有利于文件上传。

缺点

失真
首先因为没有改变Bitmap的像素值,所以文件转换成的Bitmap图片压缩后和压缩前生成的Bitmap一样大,这时候在使用的时候就要注意了,一张3000K的图片很可能生成的Bitmap多达10M,使用的时候考虑内存溢出问题。
按照官方的解释:图片重新构造, 但是有可能图像的位深(即色深)和每个像素的透明度会变化,JPEG onlysupports opaque(不透明), 也就是说以jpeg格式压缩后, 原来图片中透明的元素将消失.所以这种格式很可能造成失真。

指定图片宽高大小压缩

作用

一般用来生成缩略图,不会失真

实现

public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, os);
        if (os.toByteArray().length / 1024 > 1024) {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
            os.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, os);// 这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        newOpts.inPreferredConfig = Config.RGB_565;
        Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        float hh = pixelH;
        float ww = pixelW;
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        is = new ByteArrayInputStream(os.toByteArray());
        bitmap = BitmapFactory.decodeStream(is, null, newOpts);
        return bitmap;
    }

图标水印

    /**
     * 设置水印图片到中间
     */
    public static Bitmap createWaterMaskCenter(Bitmap src, Bitmap watermark) {
        return createWaterMaskBitmap(src, watermark,
                (src.getWidth() - watermark.getWidth()) / 2,
                (src.getHeight() - watermark.getHeight()) / 2);
    }

    public static Bitmap drawTextToLeftTop(Context context, Bitmap bitmap,
            String text) {
        return drawTextToLeftTop(context, bitmap, text, 16, Color.RED, 4, 4);
    }

    /**
     * 给图片添加文字到左上角
     */
    public static Bitmap drawTextToLeftTop(Context context, Bitmap bitmap,
            String text, int size, int color, int paddingLeft, int paddingTop) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(context, size));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        return drawTextToBitmap(context, bitmap, text, paint, bounds,
                dp2px(context, paddingLeft), dp2px(context, paddingTop)
                        + bounds.height());
    }

文字水印

    /**
     * 绘制文字到右下角
     */
    public static Bitmap drawTextToRightBottom(Context context, Bitmap bitmap,
            String text, int size, int color, int paddingRight,
            int paddingBottom) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(context, size));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        return drawTextToBitmap(
                context,
                bitmap,
                text,
                paint,
                bounds,
                bitmap.getWidth() - bounds.width()
                        - dp2px(context, paddingRight), bitmap.getHeight()
                        - dp2px(context, paddingBottom));
    }

Demo

你可能感兴趣的:(Android开发)