Bitmap总结

Bitmap可以说是图像处理中最重要的类,可以实现图像的剪切,旋转,旋转操作,我正在做的就是一个图片处理app,下面我会说一些在项目中遇到的问题和一些解决方案。

View 转换为Bitmap

第一种方式:

/**
     * view turnto bitmap
     * =======
     * 将View转为Bitmap
     * >>>>>>> master
     *
     * @param view
     * @return
     */
    public static Bitmap getViewBitmap(View view) {
        view.clearFocus(); // 清除视图焦点
        view.setPressed(false);// 将视图设为不可点击

        boolean willNotCache = view.willNotCacheDrawing();// 返回视图是否可以保存他的画图缓存
        view.setWillNotCacheDrawing(false);

        // Reset the drawing cache background color to fully transparent
        // for the duration of this operation //将视图在此操作时置为透明
        int color = view.getDrawingCacheBackgroundColor();// 获得绘制缓存位图的背景颜色
        view.setDrawingCacheBackgroundColor(0);// 设置绘图背景颜色

        if (color != 0) {// 如果获得的背景不是黑色的则释放以前的绘图缓存
            view.destroyDrawingCache();// 释放绘图资源所使用的缓存
        }
        view.buildDrawingCache();// 重新创建绘图缓存,此时的背景色是黑色
        Bitmap cacheBitmap = view.getDrawingCache();// 将绘图缓存得到的,注意这里得到的只是一个图像的引用
        if (cacheBitmap == null) {
            return null;
        }

        Bitmap bitmap = null;
        try {
            bitmap = Bitmap.createBitmap(cacheBitmap);// 将位图实例化
        } catch (OutOfMemoryError e) {
            while (bitmap == null) {
                System.gc();
                System.runFinalization();
                bitmap = createBitmap(cacheBitmap, view.getWidth(), view.getHeight());// 将位图实例化
            }
        }

        view.destroyDrawingCache();// Restore the view //恢复视图
        view.setWillNotCacheDrawing(willNotCache);// 返回以前缓存设置
        view.setDrawingCacheBackgroundColor(color);// 返回以前的缓存颜色设置

        return bitmap;
    }

第二种方式;

/**
     * 将View转为Bitmap
     *
     * @param view
     * @return
     */
    public static Bitmap convertViewToBitmap(View view) {
        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
    }

截取指定图片的中间部分 并缩放到指定宽度

/**
     * @param bitmap     原图
     * @param edgeLength 希望得到的正方形部分的边长
     * @return 缩放截取正中部分后的位图。
     */
    public static Bitmap centerSquareScaleBitmap(Bitmap bitmap, int edgeLength) {
        if (null == bitmap || edgeLength <= 0) {
            return null;
        }

        Bitmap result = bitmap.copy(Config.ARGB_8888, true);
        int widthOrg = bitmap.getWidth();
        int heightOrg = bitmap.getHeight();

        int tempWidth = 0;

        if (widthOrg < heightOrg) {
            tempWidth = widthOrg;
            result = Bitmap.createBitmap(result, 0, (heightOrg-widthOrg)/2, tempWidth, tempWidth);
        } else if (widthOrg > heightOrg) {
            tempWidth = heightOrg;
            result = Bitmap.createBitmap(result, (widthOrg - heightOrg)/2, 0, tempWidth, tempWidth);
        } else {
            //相等 正方形
        }

        result = Bitmap.createScaledBitmap(result, edgeLength, edgeLength, true);
        return result;
    }

改变bitmap 透明度

/**
     * 改变bitmap 透明度
     *
     * @param sourceImg
     * @param number
     * @return
     */
    public static Bitmap setTransparentBitmap(Bitmap sourceImg, int number) {
        int[] argb = new int[sourceImg.getWidth() * sourceImg.getHeight()];
        sourceImg.getPixels(argb, 0, sourceImg.getWidth(), 0, 0, sourceImg
                .getWidth(), sourceImg.getHeight());// 获得图片的ARGB值
        number = number * 255 / 100;
        for (int i = 0; i < argb.length; i++) {
            argb[i] = (number << 24) | (argb[i] & 0x00FFFFFF);
        }
        sourceImg = Bitmap.createBitmap(argb, sourceImg.getWidth(), sourceImg
                .getHeight(), Config.ARGB_8888);
        return sourceImg;
    }

获取圆形Bitmap

/**
     * 圆形Bitmap
     *
     * @param bitmap
     * @return
     */
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
        Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(outBitmap);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPX = bitmap.getWidth() / 2;
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPX, roundPX, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return outBitmap;
    }

文件路径或者资源文件获取bitmap对象 给定最大宽高防止内存溢出

// 图片按比例大小压缩方法
    public static Bitmap getImageFromPath(String srcPath, int maxWidth, int maxHeight) {
        /*if (!isFileAtPath(srcPath)) {
            return null;
        }*/
        try {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
            newOpts.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            LogUtils.i("bSize:newOpts.out.w=" + w + " h=" + h);

            float aBili = (float) maxHeight / (float) h;
            float bBili = (float) maxWidth / (float) w;

            int be = 1;
            if (aBili > bBili) {
                if (w > maxWidth) {
                    be = (int) (w / maxWidth);
                }
            } else {
                if (h > maxHeight) {
                    be = (int) (h / maxHeight);
                }
            }
            if (be <= 1) {//如果是放大,则不放大
                be = 1;
            }

            LogUtils.i("be===" + be);
            newOpts.inSampleSize = be;// 设置缩放比例
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

            int bwidth = bitmap.getWidth();
            int bheight = bitmap.getHeight();

            if (aBili > bBili) {
                bitmap = Bitmap.createScaledBitmap(bitmap, maxWidth, (bheight * maxWidth) / bwidth, true);
            } else {
                bitmap = Bitmap.createScaledBitmap(bitmap, (bwidth * maxHeight) / bheight, maxHeight, true);
            }

            /*int degree = readPictureDegree(srcPath);
            if (degree != 0) {
                bitmap = rotaingImageView(degree, bitmap);
            }*/
            if (bitmap == null) {
                LogUtils.i("pic null");
                return null;
            }
            return bitmap;
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }

读取图片属性 旋转的角度

/**
     * 读取图片属性:旋转的角度
     *
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

保存bitmap为png 当然可以改成其他格式

/**
     * 保存图片为JPEG
     *
     * @param bitmap
     * @param path
     */
    public static boolean saveJPGE_After(Bitmap bitmap, String path, int quality) {
        File file = new File(path);
        makeDir(file);
        try {
            FileOutputStream out = new FileOutputStream(file);
            if (bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out)) {
                out.flush();
                out.close();
            }
            //更新
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path)));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

Android中Bitmap,byte[],Drawable相互转化

1,Drawable转bitmap:

Resources res = getResources(); 
    Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.icon);

2,Bitmap → byte[]:

public byte[] Bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
         bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
         return baos.toByteArray();
     }

3,byte[] → Bitmap:

byte[] b;
BitmapFactory.decodeByteArray(b, 0, b.length);

Bitmap平移,旋转,缩放, 翻转等操作

1 平移:
平移有2种方式:
(1)通过Imageview与Matrix:

Matrix matrix=new Matrix();
    int width=bitmap.getWidth();
    int height=bitmap.getHeight();
    matrix.postTranslate(width, height);
    mImageView.setImageMatrix(matrix);

(2)通过Matrix与bitmap:

Matrix matrix=mImageView.getImageMatrix();
    int width=bitmap.getWidth();
    int height=bitmap.getHeight();
    matrix.postTranslate(width, height);
    mNewBitmap=Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
    mImageView.setImageBitmap(mNewBitmap);

2 旋转:
可以通过matrix.postRotate(rotate, x, y);, 可见Matrix 矩阵的强大,我当时看到这个的时候感受到了数学对于计算机的影响和重要性,第一个参数rotate是旋转的角度,后俩个参数是坐标,围绕哪个坐标来旋转。下面是一个把bitmap旋转任意角度的方法:

 public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
        //旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

3 缩放:
进行bitmap的缩放时一定要注意,要进行等比例缩放,如果缩放之后图片变形了就没有了它的意义,下面是我的缩放图片的方法,保持长宽比缩小bitmap:

public static Bitmap resizeBitmap(Bitmap bitmap, int maxWidth, int maxHeight) {
        int originWidth = bitmap.getWidth();
        int originHeight = bitmap.getHeight();

        // no need to resize
        if (originWidth < maxWidth && originHeight < maxHeight) {
            return bitmap;
        }

        int width = originWidth;
        int height = originHeight;

        // 若图片过宽, 则保持长宽比缩放图片
        if (originWidth > maxWidth) {
            width = maxWidth;

            double i = originWidth * 1.0 / maxWidth;
            height = (int) Math.floor(originHeight / i);

            bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
        }

        // 若图片过长, 则从上端截取
        if (height > maxHeight) {
            height = maxHeight;
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
        }

        return bitmap;
    }

4 翻转:
有的时候项目需求要求垂直翻转和水平翻转, sourceBitmap为你要旋转的bitmap

(1)垂直翻转:

 Matrix m = new Matrix();
m.postScale(1, -1);   //镜像垂直翻转
Bitmap newBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), m, true);

(2)水平翻转:

Matrix m = new Matrix();
m.postScale(-1, 1);   //镜像水平翻转
Bitmap newBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), m, true);

通过bitmap,ColorMatrix改变图片的 亮度,对比度, 饱和度,其中 AppConst.cropperImg为原图

1 改变亮度:

Bitmap brightness_bmp = Bitmap.createBitmap(AppConst.cropperImg.getWidth(), AppConst.cropperImg.getHeight(),
                        Bitmap.Config.ARGB_8888);
                int brightness = 127 - progress;
                ColorMatrix brightness_cMatrix = new ColorMatrix();
                brightness_cMatrix.set(new float[]{1, 0, 0, 0, brightness, 0, 1,
                        0, 0, brightness,// 改变亮度
                        0, 0, 1, 0, brightness, 0, 0, 0, 1, 0});

                Paint brightness_paint = new Paint();
                Canvas brightness_canvas = new Canvas(brightness_bmp);
                brightness_paint.setColorFilter(new ColorMatrixColorFilter(brightness_cMatrix));

                // 在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
                brightness_canvas.drawBitmap(AppConst.cropperImg, 0, 0, brightness_paint);
// 将最终图片设置到控件上            
beautify_gpuimage.setImage(brightness_bmp);

2 曝光度:

//曝光度
                Bitmap contrast_bmp = Bitmap.createBitmap(AppConst.cropperImg.getWidth(), AppConst.cropperImg.getHeight(),
                        Bitmap.Config.ARGB_8888);
                // int brightness = progress - 127;
                float contrast = (float) ((progress + 64) / 128.0);
                ColorMatrix contrast_cMatrix = new ColorMatrix();
                contrast_cMatrix.set(new float[]{contrast, 0, 0, 0, 0, 0,
                        contrast, 0, 0, 0,// 改变对比度
                        0, 0, contrast, 0, 0, 0, 0, 0, 1, 0});

                Paint contrast_paint = new Paint();
                contrast_paint.setColorFilter(new ColorMatrixColorFilter(contrast_cMatrix));

                Canvas contrast_canvas = new Canvas(contrast_bmp);
                // 在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
                contrast_canvas.drawBitmap(AppConst.cropperImg, 0, 0, contrast_paint);

                beautify_gpuimage.setImage(contrast_bmp);

3, 对比度:

//对比度
                Bitmap bmp = Bitmap.createBitmap(AppConst.cropperImg.getWidth(), AppConst.cropperImg.getHeight(),
                        Bitmap.Config.ARGB_8888);
                ColorMatrix cMatrix = new ColorMatrix();
                // 设置饱和度
                cMatrix.setSaturation((float) (progress / 100.0));

                Paint paint = new Paint();
                paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));

                Canvas canvas = new Canvas(bmp);
                // 在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
                canvas.drawBitmap(AppConst.cropperImg, 0, 0, paint);

                beautify_gpuimage.setImage(bmp);

以上都是在做项目的过程中用到的对图片操作的总结,基本通过Bitmap都可以做到

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值