您的位置:首页 > 移动开发 > Android开发

android 处理图片之--bitmap处理

2015-08-19 19:42 323 查看
-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 = (number << 24) | (argb & 0×00FFFFFF);// 修改最高2[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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: