android的Bitmap和Drawable用法

//方法: 
//1 生成圆角Bitmap图片 
//2 生成Bitmap缩量图 
//3 压缩图片场长宽以及kB 
//注意: 
//以上代码,测试其中一个方法时最好注释掉其余的代码 
public class MainActivity extends Activity { 
private ImageView imageView; 
private Bitmap copyRawBitmap1; 
private Bitmap copyRawBitmap2; 
private Bitmap copyRawBitmap3; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.main); 
imageView = (ImageView) findViewById(R.id.imageView); 
//第一种方式:从资源文件中得到图片 
Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.haha); 
copyRawBitmap1=rawBitmap; 
copyRawBitmap2=rawBitmap; 
copyRawBitmap3=rawBitmap; 
//第二种方式:从SD卡中得到图片(方法1) 
String SDCarePath=Environment.getExternalStorageDirectory().toString(); 
String filePath=SDCarePath+"/"+"haha.jpg"; 
Bitmap rawBitmap1 = BitmapFactory.decodeFile(filePath, null); 
//第二种方式:从SD卡中得到图片(方法2) 
InputStream inputStream=getBitmapInputStreamFromSDCard("haha.jpg"); 
Bitmap rawBitmap2 = BitmapFactory.decodeStream(inputStream); 

//————>以下为将设置图片的圆角 
Bitmap roundCornerBitmap=this.toRoundCorner(rawBitmap, 40); 
imageView.setImageBitmap(roundCornerBitmap); 
//————>以上为将设置图片的圆角 

//————>以下为将图片高宽和的大小kB压缩 
// 得到图片原始的高宽 
int rawHeight = rawBitmap.getHeight(); 
int rawWidth = rawBitmap.getWidth(); 
// 设定图片新的高宽 
int newHeight = 500; 
int newWidth = 500; 
// 计算缩放因子 
float heightScale = ((float) newHeight) / rawHeight; 
float widthScale = ((float) newWidth) / rawWidth; 
// 新建立矩阵 
Matrix matrix = new Matrix(); 
matrix.postScale(heightScale, widthScale); 
// 设置图片的旋转角度 
//matrix.postRotate(-30); 
// 设置图片的倾斜 
//matrix.postSkew(0.1f, 0.1f); 
//将图片大小压缩 
//压缩后图片的宽和高以及kB大小均会变化 
Bitmap newBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, rawWidth,rawWidth, matrix, true); 
// 将Bitmap转换为Drawable 
Drawable newBitmapDrawable = new BitmapDrawable(newBitmap); 
imageView.setImageDrawable(newBitmapDrawable); 
//然后将Bitmap保存到SDCard中,方便于原图片的比较 
this.compressAndSaveBitmapToSDCard(newBitmap, "xx100.jpg", 80); 
//问题: 
//原图大小为625x690 90.2kB 
//如果设置图片500x500 压缩后大小为171kB.即压缩后kB反而变大了. 
//原因是将:compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream); 
//第二个参数quality设置得有些大了(比如100). 
//常用的是80,刚设100太大了造成的. 
//————>以上为将图片高宽和的大小kB压缩 


//————>以下为将图片的kB压缩,宽高不变 
this.compressAndSaveBitmapToSDCard(copyRawBitmap1,"0011fa.jpg",80); 
//————>以上为将图片的kB压缩,宽高不变 

//————>以下为获取SD卡图片的缩略图方法1 
String SDCarePath1=Environment.getExternalStorageDirectory().toString(); 
String filePath1=SDCarePath1+"/"+"haha.jpg"; 
Bitmap bitmapThumbnail1=this.getBitmapThumbnail(filePath1); 
imageView.setImageBitmap(bitmapThumbnail1); 
//————>以上为获取SD卡图片的缩略图方法1 

//————>以下为获取SD卡图片的缩略图方法2 
String SDCarePath2=Environment.getExternalStorageDirectory().toString(); 
String filePath2=SDCarePath2+"/"+"haha.jpg"; 
Bitmap tempBitmap=BitmapFactory.decodeFile(filePath2); 
Bitmap bitmapThumbnail2=ThumbnailUtils.extractThumbnail(tempBitmap, 100, 100); 
imageView.setImageBitmap(bitmapThumbnail2); 
//————>以上为获取SD卡图片的缩略图方法2 

} 
//读取SD卡下的图片 
private InputStream getBitmapInputStreamFromSDCard(String fileName){ 
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 
String SDCarePath=Environment.getExternalStorageDirectory().toString(); 
String filePath=SDCarePath+File.separator+fileName; 
File file=new File(filePath); 
try { 
FileInputStream fileInputStream=new FileInputStream(file); 
return fileInputStream; 
} catch (Exception e) { 
e.printStackTrace(); 
} 
} 
return null; 
} 

//获取SDCard的目录路径功能 
private String getSDCardPath() { 
String SDCardPath = null; 
// 判断SDCard是否存在 
boolean IsSDcardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); 
if (IsSDcardExist) { 
SDCardPath = Environment.getExternalStorageDirectory().toString(); 
} 
return SDCardPath; 
} 
//压缩且保存图片到SDCard 
private void compressAndSaveBitmapToSDCard(Bitmap rawBitmap,String fileName,int quality){ 
String saveFilePaht=this.getSDCardPath()+File.separator+fileName; 
File saveFile=new File(saveFilePaht); 
if (!saveFile.exists()) { 
try { 
saveFile.createNewFile(); 
FileOutputStream fileOutputStream=new FileOutputStream(saveFile); 
if (fileOutputStream!=null) { 
//imageBitmap.compress(format, quality, stream); 
//把位图的压缩信息写入到一个指定的输出流中 
//第一个参数format为压缩的格式 
//第二个参数quality为图像压缩比的值,0-100.0 意味着小尺寸压缩,100意味着高质量压缩 
//第三个参数stream为输出流 
rawBitmap.compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream); 
} 
fileOutputStream.flush(); 
fileOutputStream.close(); 
} catch (IOException e) { 
e.printStackTrace(); 

} 
} 
} 

//获取图片的缩略图 
private Bitmap getBitmapThumbnail(String filePath){ 
BitmapFactory.Options options=new BitmapFactory.Options(); 
//true那么将不返回实际的bitmap对象,不给其分配内存空间但是可以得到一些解码边界信息即图片大小等信息 
options.inJustDecodeBounds=true; 
//此时rawBitmap为null 
Bitmap rawBitmap = BitmapFactory.decodeFile(filePath, options); 
if (rawBitmap==null) { 
System.out.println("此时rawBitmap为null"); 
} 
//inSampleSize表示缩略图大小为原始图片大小的几分之一,若该值为3 
//则取出的缩略图的宽和高都是原始图片的1/3,图片大小就为原始大小的1/9 
//计算sampleSize 
int sampleSize=computeSampleSize(options, 150, 200*200); 
//为了读到图片,必须把options.inJustDecodeBounds设回false 
options.inJustDecodeBounds = false; 
options.inSampleSize = sampleSize; 
//原图大小为625x690 90.2kB 
//测试调用computeSampleSize(options, 100, 200*100); 
//得到sampleSize=8 
//得到宽和高位79和87 
//79*8=632 87*8=696 
Bitmap thumbnailBitmap=BitmapFactory.decodeFile(filePath, options); 
//保存到SD卡方便比较 
this.compressAndSaveBitmapToSDCard(thumbnailBitmap, "15.jpg", 80); 
return thumbnailBitmap; 
} 

//参考资料: 
//http://my.csdn.net/zljk000/code/detail/18212 
//第一个参数:原本Bitmap的options 
//第二个参数:希望生成的缩略图的宽高中的较小的值 
//第三个参数:希望生成的缩量图的总像素 
public static int computeSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) { 
int initialSize = computeInitialSampleSize(options, minSideLength,maxNumOfPixels); 
int roundedSize; 
if (initialSize <= 8) { 
roundedSize = 1; 
while (roundedSize < initialSize) { 
roundedSize <<= 1; 
} 
} else { 
roundedSize = (initialSize + 7) / 8 * 8; 
} 
return roundedSize; 
} 

private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) { 
//原始图片的宽 
double w = options.outWidth; 
//原始图片的高 
double h = options.outHeight; 
System.out.println("========== w="+w+",h="+h); 
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math 
.sqrt(w * h / maxNumOfPixels)); 
int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( 
Math.floor(w / minSideLength), Math.floor(h / minSideLength)); 
if (upperBound < lowerBound) { 
// return the larger one when there is no overlapping zone. 
return lowerBound; 
} 
if ((maxNumOfPixels == -1) && (minSideLength == -1)) { 
return 1; 
} else if (minSideLength == -1) { 
return lowerBound; 
} else { 
return upperBound; 
} 
} 

/** 
* @param bitmap 需要修改的图片 
* @param pixels 圆角的弧度 
* @return 圆角图片 
*/ 
//参考资料: 
//http://blog.csdn.net/c8822882/article/details/6906768 
public Bitmap toRoundCorner(Bitmap bitmap, int pixels) { 
Bitmap roundCornerBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); 
Canvas canvas = new Canvas(roundCornerBitmap); 
int color = 0xff424242;//int color = 0xff424242; 
Paint paint = new Paint(); 
paint.setColor(color); 
//防止锯齿 
paint.setAntiAlias(true); 
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 
RectF rectF = new RectF(rect); 
float roundPx = pixels; 
//相当于清屏 
canvas.drawARGB(0, 0, 0, 0); 
//先画了一个带圆角的矩形 
canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
//再把原来的bitmap画到现在的bitmap!!!注意这个理解 
canvas.drawBitmap(bitmap, rect, rect, paint); 
return roundCornerBitmap; 
} 
}  

Bitmap 是 Android系统图像处理的类,可用于获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定图像文件保存操作
Bitmap类常用方法
(1public final int getHeight():获取位图宽度
(2)public final int getWidth():获取位图高度
(3)public static Bitmap createBitmap(Bitmap src):通过位图资源创建位图实例
(4)public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height):在指定位置创建位图,可放大缩小位图  source是位图资源,(x,y)表示位图左上角坐标,width表示位图宽度,height表示位图高度
(5)public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrixm, boolean filter):截取位图中指定区域中的位图  source是目标位图资源,(x,y)表示剪切位图左上角起始点坐标,width表示目标位图宽度,height表示目标位图高度,m表示选择区域,filter是当其为true且m表示的区域大于前面参数所描述的区域时就填充截取的位图空白处(6)public boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream):保存图像文件  format是图片保存格式,quality是图片压缩的质量取值在0-100之间 0表示压缩的最小尺寸 100表示压缩的最好质量,stream是图片的输出流
注:对于PNG格式的图片是有损压缩的,quality压缩图片是没有效果的,该参数的设置无影响

Bitmap.CompressFormat
(1)public static final Bitmap.CompressFormat JPEG:保存图片合适成JPEG格式
(2)public static final Bitmap.CompressFormat PNG:保存图片合适成PNG格式
获取Bitmap
Bitmap可以通过 BitmapFactory的 decode系列方法来获取 Bitmap对象
BitmapFactory类

(1)public static Bitmap decodeFile(String pathName):将图片文件路径解码成图片的 Bitmap对象,要是图片不存在或是pathName为空则返回null
(2)public static BitmapdecodeStream(InputStream is):将输入流中的数据解码成图片的 Bitmap对象,要是is为空或无法解码成图片键返回null
(3)public static Bitmap decodeResource(Resources res, int id):通过资源id解码资源成图片的 Bitmap对象  res是包含图片数据的资源对象  id是图片数据的资源id

BitmapFacotry.Options 
public static Bitmap decodeFile(String pathName, BitmapFactory.Options opts) 和 public staticBitmap decodeResource(Resources res, int id, BitmapFactory.Options opts) 都指定一个BitmapFacotry.Options 该值指定指定解码的相关属性,其值可以为:

(1)public Bitmap.Config inPreferredConfig: 指定decode到内存中,手机中所采用的编码,可选值定义在Bitmap.Config中。缺省值是ARGB_8888
(2)public boolean inJustDecodeBounds:如果设置为true,并不会把图像的数据完全解码,亦即decodeXyz()返回值为null,但是Options的outAbc中解出了图像的基本信息
(3)public intinSampleSize:设置decode时的缩放比例,当该数据大于1时将会压缩图片到原图片的 1/inSampleSize 大小,当改值小于等于1是将会被视作1不会压缩图片

加载Bitmap图片
(1)通过文件路径加载位图,显示原图,大小比例不变
Bitmap bmp=BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg");  
imageView.setImageBitmap(bmp);
(2)通过文件路径加载位图,(若scale 值为n>1) 则图片长,宽变为原来的1/n,相当于把图片压缩到原来的1/(n*n),加载到手机内存占用的空间小,可以在xml文件中设置ImageView的scaleType=fitCenter属性,进行拉伸自适应操作,拉伸后的图像不是很清楚,但还是可以接受的
Options options=new Options();  
options.inSampleSize=2;   
Bitmap bm=BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", options);  
imageView.setImageBitmap(bm);
(3)通过文件路径加载位图,此种方式,可以把原图缩小,或放大
Options opts=new Options();  
//设置仅加载位图边界信息(相当于位图的信息,但没有加载位图)
opts.inJustDecodeBounds=true;
//加载指定路径图片的边界信息,保存到opts中
BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", opts);  
//计算收缩比例
int xScale=opts.outWidth/200;  
int yScale=opts.outHeight/200;  
opts.inSampleSize=xScale>yScale?xScale:yScale;  
//设置加载边界信息为false
opts.inJustDecodeBounds=false;  
Bitmap bm=BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", opts);  
imageView.setImageBitmap(bm);
(4)通过输入流加载位图
FileInputStream is;  
try {  
is = new FileInputStream("/mnt/sdcard/dog.jpg");  
Bitmap bm=BitmapFactory.decodeStream(is);  
imageView.setImageBitmap(bm);  
} catch (FileNotFoundException e) {  
    e.printStackTrace();  
}
(5)通过字节数组加载位图,图片长,宽减半
//从网络上读取图片的字符串数组(输入流)  
//字节数组输出流 
try {  
FileInputStream fis=new FileInputStream("/mnt/sdcard/dog.jpg");  
BufferedInputStream bis=new BufferedInputStream(fis);  
out = new ByteArrayOutputStream();  
int hasRead=0;  
byte[] buffer=new byte[1024*2];  
while((hasRead=bis.read(buffer))>0){  
//读出多少数据,向输出流中写入多少
out.write(buffer);  
out.flush();
}  
out.close();  
fis.close();  
bis.close();  
byte[] data=out.toByteArray();  
//长宽减半
Options opts=new Options();  
opts.inSampleSize=2;  
Bitmap bm=BitmapFactory.decodeByteArray(data, 0, data.length, opts);  
imageView.setImageBitmap(bm);
} catch (FileNotFoundException e) { 
e.printStackTrace();  
} catch (IOException e) {  
e.printStackTrace();  
}

上面这个代码文件里面详细介绍了Bitmap类的用法,相信各位看过之后对于Bitmap的用法已经了解。下面讲解Drawable类。
一、相关概念
1、Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),还有可能是一个图层(LayerDrawable),我们根据画图的需求,创建相应的可画对象2、Canvas画布,绘图的目的区域,用于绘图3、Bitmap位图,用于图的处理4、Matrix矩阵二、Bitmap
1、从资源中获取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
代码如下

public Bitmap Bytes2Bimap(byte[] b) { 
    if (b.length != 0) { 
        return BitmapFactory.decodeByteArray(b, 0, b.length); 
    } else { 
        return null; 
    } 
}

Bitmap缩放
代码如下

public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) { 
    int w = bitmap.getWidth(); 
    int h = bitmap.getHeight(); 
    Matrix matrix = new Matrix(); 
    float scaleWidth = ((float) width / w); 
    float scaleHeight = ((float) height / h); 
    matrix.postScale(scaleWidth, scaleHeight); 
    Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true); 
    return newbmp; 
}

5、将Drawable转化为Bitmap
代码如下

public static Bitmap drawableToBitmap(Drawable drawable) { 
        // 取 drawable 的长宽 
        int w = drawable.getIntrinsicWidth(); 
        int h = drawable.getIntrinsicHeight(); 
        // 取 drawable 的颜色格式 
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 
                : Bitmap.Config.RGB_565; 
        // 建立对应 bitmap 
        Bitmap bitmap = Bitmap.createBitmap(w, h, config); 
        // 建立对应 bitmap 的画布 
        Canvas canvas = new Canvas(bitmap); 
        drawable.setBounds(0, 0, w, h); 
        // 把 drawable 内容画到画布中 
        drawable.draw(canvas); 
        return bitmap; 
    }

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) { 
    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, roundPx, roundPx, paint); 
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
    canvas.drawBitmap(bitmap, rect, rect, paint); 
    return output; 
}

6、获得圆角图片
代码如下

public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) { 
    final int reflectionGap = 4; 
    int w = bitmap.getWidth(); 
    int h = bitmap.getHeight(); 
    Matrix matrix = new Matrix(); 
    matrix.preScale(1, -1); 
    Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, h / 2, w, 
            h / 2, matrix, false); 
    Bitmap bitmapWithReflection = Bitmap.createBitmap(w, (h + h / 2), 
            Config.ARGB_8888); 
    Canvas canvas = new Canvas(bitmapWithReflection); 
    canvas.drawBitmap(bitmap, 0, 0, null); 
    Paint deafalutPaint = new Paint(); 
    canvas.drawRect(0, h, w, h + reflectionGap, deafalutPaint); 
    canvas.drawBitmap(reflectionImage, 0, h + 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, h, w, bitmapWithReflection.getHeight() 
            + reflectionGap, paint); 
    return bitmapWithReflection; 
}

三、Drawable
代码如下

Bitmap bm=xxx; //xxx根据你的情况获取 
BitmapDrawable bd= new BitmapDrawable(getResource(), bm); 

因为BtimapDrawable是Drawable的子类,最终直接使用bd对象即可。
2、Drawable缩放
代码如下

public static Drawable zoomDrawable(Drawable drawable, int w, int h) { 
    int width = drawable.getIntrinsicWidth(); 
    int height = drawable.getIntrinsicHeight(); 
    // drawable转换成bitmap 
    Bitmap oldbmp = drawableToBitmap(drawable); 
    // 创建操作图片用的Matrix对象 
    Matrix matrix = new Matrix(); 
    // 计算缩放比例 
    float sx = ((float) w / width); 
    float sy = ((float) h / height); 
    // 设置缩放比例 
    matrix.postScale(sx, sy); 
    // 建立新的bitmap,其内容是对原bitmap的缩放后的图 
    Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, 
            matrix, true); 
    return new BitmapDrawable(newbmp); 
}

这篇博文整理得到,各位看到别的地方有相同内容,无疑!感谢贡献者的无私!没有注明出处,请见谅!【握手】

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值