zoukankan      html  css  js  c++  java
  • android 处理图片之--bitmap处理

    -2、从资源中获得bitmap

    Resources res=getResources();
    Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic);
    或者
    Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();

        /**
         * 以最省内存的方式读取本地资源的图片
         *
         * @param context
         * @param resId
         * @return
         */
        public Bitmap readBitMap(int resId) {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inPreferredConfig = Bitmap.Config.RGB_565;
            opt.inPurgeable = true;
            opt.inInputShareable = true;
            // 获取资源图片
            InputStream is = getResources().openRawResource(resId);
            return BitmapFactory.decodeStream(is, null, opt);
        }

    -1、Drawable 转 Bitmap

    public static Bitmap drawableToBitmap(Drawable drawable) {  
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                drawable.getIntrinsicHeight(),
                drawable.getOpacity() != PixelFormat.OPAQUE ?
                        Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);  
                        Canvas canvas = new Canvas(bitmap);  
                        //canvas.setBitmap(bitmap);  
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  
        drawable.draw(canvas);  
        return bitmap;  
    }  



    0、读取一个bitmap
        /**
         * 节省内存
         *
         * @Description:
         * @param filePath
         * @param outWidth
         * @param outHeight
         * @return
         * @see:
         * @since:
         * @author: zhuanggy
         * @date:2013-3-12
         */
        public static Bitmap readBitmapAutoSize(String filePath, int outWidth, int outHeight) {
            // outWidth和outHeight是目标图片的最大宽度和高度,用作限制
            FileInputStream fs = null;
            BufferedInputStream bs = null;
            try {
                fs = new FileInputStream(filePath);
                bs = new BufferedInputStream(fs);
                BitmapFactory.Options options = setBitmapOption(filePath, outWidth, outHeight);
                return BitmapFactory.decodeStream(bs, null, options);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    bs.close();
                    fs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        private static BitmapFactory.Options setBitmapOption(String file, int width, int height) {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inJustDecodeBounds = true;
            // 设置只是解码图片的边距,此操作目的是度量图片的实际宽度和高度
            BitmapFactory.decodeFile(file, opt);

            int outWidth = opt.outWidth; // 获得图片的实际高和宽
            int outHeight = opt.outHeight;
            opt.inDither = false;
            opt.inPreferredConfig = Bitmap.Config.RGB_565;
            // 设置加载图片的颜色数为16bit,默认是RGB_8888,表示24bit颜色和透明通道,但一般用不上
            opt.inSampleSize = 1;
            // 设置缩放比,1表示原比例,2表示原来的四分之一....
            // 计算缩放比
            if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0) {
                int sampleSize = (outWidth / width + outHeight / height) / 2;
                opt.inSampleSize = sampleSize;
            }

            opt.inJustDecodeBounds = false;// 最后把标志复原
            return opt;
        }



    1、透明度处理

    /**
    * 图片透明度处理
    *
    * @param sourceImg
    * 原始图片
    * @param number
    * 透明度
    * @return
    */
    public static Bitmap setAlpha(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 & 0×00FFFFFF);// [/i][i]修改最高2[/i][i]位的值
    }
    sourceImg = Bitmap.createBitmap(argb, sourceImg.getWidth(), sourceImg.getHeight(), Config.ARGB_8888);
    return sourceImg;
    }


    2、获得圆角bitmap

        /**
         * 获得圆角图片
         *
         * @Description:
         * @param bitmap
         * @param roundPx
         * @return
         * @see:
         * @since:
         * @author: zhuanggy
         * @date:2013-3-14
         */
        public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();
            Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
            Canvas canvas = new Canvas(output);
            final int color = 0xff424242;
            final Paint paint = new Paint();
            final Rect rect = new Rect(0, 0, w, h);
            final RectF rectF = new RectF(rect);
            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(color);
            canvas.drawRoundRect(rectF, 10, 10, paint);// 圆角平滑度为10
            paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
            canvas.drawBitmap(bitmap, rect, rect, paint);

            return output;
        }


    3、截取 Bitmap 的部分区域

    mBitmap = Bitmap.createBitmap(bmp, 100, 100, 120, 120);


    4、缩放一个 Bitmap
    可以用 Bitmap.createScaledBitmap() 方 法根据给定的 Bitmap 创建 一个新的,缩放后的 Bitmap 。


    Bitmap mBitmap = Bitmap.createScaledBitmap(bmp, mScreenWidth, mScreenHeight, true);  

    其中 mScreenWidth 和 mScreenHeight 是屏幕的宽度和高度,这里就将 bmp 拉伸到整个屏幕。
        每次 createBitmap ,都会分配新的内存,带来资源的 消耗,所以用 Bitmap 的 createBitmap 虽然简单方便,但是不是最优方 法。介绍一个比较好点的方法,不用创建新的 Bitmap ,用 Canvas 在画的时候直接缩放或者剪切


    canvas.drawBitmap(mBitmap, null, new Rect(0, 0, 200, 200), null);  

    这里的 Rect 对象表示一个矩形区域,从 (0,0) 到 (200,200) 之间的矩形区域。这段代码将把 mBitmap 缩放并绘制到屏幕上的(0,0) 到 (200,200) 之间的区域。这个方法还有第二个参数我给的是 null ,其实这个参数也是个 Rect 对象,表示源 Rect 。把图片的某个区域拿出来画到屏幕的指定区域,


    canvas.drawBitmap(mBitmap, new Rect(100, 100, 300, 300), new Rect(100, 100, 200, 200), null);
    这里将 mBitmap 的 (100,100) 到 (300,300) 区域拿出来,自动缩放并画到屏幕的 (100,100) 到 (200,200) 区域。



    5、图片平均分割方法,将大图平均分割为N行N列,方便用户使用
    /***
    * 图片分割
    *
    * @param g
    * :画布
    * @param paint
    * :画笔
    * @param imgBit
    * :图片
    * @param x
    * :X轴起点坐标
    * @param y
    * :Y轴起点坐标
    * @param w
    * :单一图片的宽度
    * @param h
    * :单一图片的高度
    * @param line
    * :第几列
    * @param row
    * :第几行
    */

    public final void cuteImage(Canvas g, Paint paint, Bitmap imgBit, int x,
    int y, int w, int h, int line, int row) {
    g.clipRect(x, y, x + w, h + y);
    g.drawBitmap(imgBit, x – line * w, y – row * h, paint);
    g.restore();
    }

    6、 图片缩放,对当前图片进行缩放处理


    public Bitmap zoomImage(Bitmap bgimage, int newWidth, int newHeight) {

    // 获取这个图片的宽和高

    int width = bgimage.getWidth();
    int height = bgimage.getHeight();

    // 创建操作图片用的matrix对象
    Matrix matrix = new Matrix();

    // 计算缩放率,新尺寸除原始尺寸
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;

    // 缩放图片动作
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, width, height,
    matrix, true);
    return bitmap;

    }


    7、绘制带有边框的文字,一般在游戏中起文字的美化作用
    /***
    * 绘制带有边框的文字
    *
    * @param strMsg
    * :绘制内容
    * @param g
    * :画布
    * @param paint
    * :画笔
    * @param setx
    * ::X轴起始坐标
    * @param sety
    * :Y轴的起始坐标
    * @param fg
    * :前景色
    * @param bg
    * :背景色
    */


    public void drawText(String strMsg, Canvas g, Paint paint, int setx,
    int sety, int fg, int bg) {
    paint.setColor(bg);
    g.drawText(strMsg, setx + 1, sety, paint);
    g.drawText(strMsg, setx, sety – 1, paint);
    g.drawText(strMsg, setx, sety + 1, paint);
    g.drawText(strMsg, setx – 1, sety, paint);
    paint.setColor(fg);
    g.drawText(strMsg, setx, sety, paint);
    g.restore();

    }


    8、图片翻转

    Resources res = this.getContext().getResources();
    img = BitmapFactory.decodeResource(res, R.drawable.slogo);
    Matrix matrix = new Matrix();
    matrix.postRotate(90);
     /*翻转90度*/
    int width = img.getWidth();
    int height = img.getHeight();
    r_img = Bitmap.createBitmap(img, 0, 0, width, height, matrix, true);


    9、带倒影的效果

    //获得带倒影的图片方法    
    public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap){    
        final int reflectionGap = 4;    
        int width = bitmap.getWidth();    
        int height = bitmap.getHeight();    
                
        Matrix matrix = new Matrix();    
        matrix.preScale(1, -1);    
                
        Bitmap reflectionImage = Bitmap.createBitmap(bitmap,0, height/2, width, height/2, matrix, false);    
                    
        Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height/2), Config.ARGB_8888);    
                    
        Canvas canvas = new Canvas(bitmapWithReflection);    
        canvas.drawBitmap(bitmap, 0, 0, null);    
        Paint deafalutPaint = new Paint();    
        canvas.drawRect(0, height,width,height + reflectionGap,    
        deafalutPaint);    
           
        canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);    
                 
        Paint paint = new Paint();    
        LinearGradient shader = new LinearGradient(0,    
        bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);    
        paint.setShader(shader);    
        // Set the Transfer mode to be porter duff and destination in    
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));    
        // Draw a rectangle using the paint with our linear gradient    
        canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);    
             
        return bitmapWithReflection;    
    }  













    另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应, 使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。 可参考下面的代码

    BitmapFactory.Options opts = new BitmapFactory.Options();
    //设置图片的DPI为当前手机的屏幕dpi
    opts.inTargetDensity = ctx.getResources().getDisplayMetrics().densityDpi;  
    opts.inScaled = true;

    另外,图片的bitmap对象为大对象,不用了要注意主动回收,

     if(!bmp.isRecycle() ){
             bmp.recycle()   //回收图片所占的内存
             system.gc()  //提醒系统及时回收
    }








    【我的应用】:

        /**
         * 读取本地图片的bitmap
         *
         * @Description:
         * @param filePath
         * @param outWidth
         * @param outHeight
         * @return
         * @see:
         * @since:
         * @author: zhuanggy
         * @date:2013-3-12
         */
        public static Bitmap readBitmapAutoSize(String filePath, int outWidth, int outHeight) {
            // outWidth和outHeight是目标图片的最大宽度和高度,用作限制
            FileInputStream fs = null;
            BufferedInputStream bs = null;
            try {
                fs = new FileInputStream(filePath);
                bs = new BufferedInputStream(fs);
                BitmapFactory.Options options = setBitmapOption(filePath, outWidth, outHeight);
                return BitmapFactory.decodeStream(bs, null, options);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    bs.close();
                    fs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        private static BitmapFactory.Options setBitmapOption(String file, int width, int height) {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inJustDecodeBounds = true;
            // 设置只是解码图片的边距,此操作目的是度量图片的实际宽度和高度
            BitmapFactory.decodeFile(file, opt);

            int outWidth = opt.outWidth; // 获得图片的实际高和宽
            int outHeight = opt.outHeight;

            GoOutDebug.e(TAG, "outWidth=" + outWidth + "  outHeight=" + outHeight);

            opt.inDither = false;
            opt.inPreferredConfig = Bitmap.Config.RGB_565;
            // 设置加载图片的颜色数为16bit,默认是RGB_8888,表示24bit颜色和透明通道,但一般用不上
            opt.inSampleSize = 1;

            // 设置缩放比,1表示原比例,2表示原来的四分之一....
            if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0) {
                int sampleSize = (outWidth / width + outHeight / height) / 2;
                opt.inSampleSize = sampleSize;
            }

            opt.inJustDecodeBounds = false;// 最后把标志复原
            return opt;
        }

        /**
         * 获得圆角图片
         *
         * @Description:
         * @param bitmap
         * @param roundPx
         * @return
         * @see:
         * @since:
         * @author: zhuanggy
         * @date:2013-3-14
         */
        public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int width, int height) {
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();

            // 若读取图片的宽度或高度小于ImageView的宽度或高度,则对图片进行放大
            if (w < width || h < height) {
                Matrix matrix = new Matrix();
                matrix.postScale((float) width / w, (float) height / h); // 长和宽放大缩小的比例
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            }
            // GoOutDebug.e(TAG, "w = " + output.getWidth() + "   h = " + output.getHeight());
            // 创建一个新的bitmap,然后在bitmap里创建一个圆角画布,将之前的图片画在里面。
            Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
            Canvas canvas = new Canvas(output);
            final int color = 0xff424242;
            final Paint paint = new Paint();
            final Rect rect = new Rect(0, 0, width, height);
            final RectF rectF = new RectF(rect);
            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(color);
            canvas.drawRoundRect(rectF, 10, 10, paint);// 圆角平滑度
            paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
            canvas.drawBitmap(bitmap, rect, rect, paint);

            return output;
        }

  • 相关阅读:
    P1019 单词接龙
    最小生成树模板题POJ
    区间DP
    牛客多校第三场-A-PACM Team-多维背包的01变种
    洛谷P1004 方格取数-四维DP
    牛客多校第二场A run(基础DP)
    P1494 [国家集训队]小Z的袜子(莫队)
    洛谷:过河卒
    Codeforces Round #486 (Div. 3)-B. Substrings Sort
    判断的值是否为空
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3435872.html
Copyright © 2011-2022 走看看