Android Bitmap详细介绍

代码如下:

package com.testbitmapscale;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import com.testbitmapscale.R.drawable;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.ImageView;
//方法:
//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;
}

}

(0)

相关推荐

  • Android的Activity跳转动画各种效果整理

    大家使用Android的原生UI都知道,Android的Activity跳转就是很生硬的切换界面.其实Android的Activity跳转可以设置各种动画.下面给大家看看效果:  实现非常简单,用overridePendingtransition(int inId, int outId)即可实现.inId是下一界面进入效果的xml文件的id,outId是当前界面退出效果的xml文件id. 效果是用xml文件写的,首先要在res文件夹下建立anim文件夹,然后把动画效果xml文件放到里面去. 下面

  • Android 动画之ScaleAnimation应用详解

    android中提供了4中动画: AlphaAnimation 透明度动画效果 ScaleAnimation 缩放动画效果 TranslateAnimation 位移动画效果 RotateAnimation 旋转动画效果 本节讲解ScaleAnimation 动画, ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, float pivotXValue, int pivotYType, flo

  • android客户端从服务器端获取json数据并解析的实现代码

    首先客户端从服务器端获取json数据 1.利用HttpUrlConnection 复制代码 代码如下: /**      * 从指定的URL中获取数组      * @param urlPath      * @return      * @throws Exception      */     public static String readParse(String urlPath) throws Exception {                  ByteArrayOutputSt

  • Android SQLite数据库增删改查操作的使用详解

    一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NULL.INTEGER.REAL(浮点数字). TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n). char(n).decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型. SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段

  • android Handler详细使用方法实例

    开发环境为android4.1.Handler使用例1这个例子是最简单的介绍handler使用的,是将handler绑定到它所建立的线程中.本次实验完成的功能是:单击Start按钮,程序会开始启动线程,并且线程程序完成后延时1s会继续启动该线程,每次线程的run函数中完成对界面输出nUpdateThread...文字,不停的运行下去,当单击End按钮时,该线程就会停止,如果继续单击Start,则文字又开始输出了. 软件界面如下: 实验主要部分代码和注释: MainActivity.java: 复

  • Android中backgroundDimEnabled的作用

    Android中backgroundDimEnabled的作用 <style name="CustomDialogStyle" parent="@android:style/Theme.Dialog"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windo

  • android调试工具DDMS的使用详解

    具体可见http://developer.android.com/tools/debugging/ddms.html. DDMS为IDE和emultor.真正的android设备架起来了一座桥梁.开发人员可以通过DDMS看到目标机器上运行的进程/现成状态,可以 android的屏幕到开发机上,可以看进程的heap信息,可以查看logcat信息,可以查看进程分配内存情况,可以像目标机发送短信以及打电话,可 以像android开发发送地理位置信息.可以像gdb一样attach某一个进程调试. SDK

  • android PopupWindow 和 Activity弹出窗口实现方式

    本人小菜一个.目前只见过两种弹出框的实现方式,第一种是最常见的PopupWindow,第二种也就是Activity的方式是前几天才见识过.感觉很霸气哦.没想到,activity也可以做伪窗口. 先贴上最常见的方法,主要讲activity的方法. 一.弹出PopupWindow 复制代码 代码如下: /** * 弹出menu菜单 */ public void menu_press(){ if(!menu_display){ //获取LayoutInflater实例 inflater = (Layo

  • Android Bitmap详细介绍

    复制代码 代码如下: package com.testbitmapscale; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import com.testbitmapscale.R.drawable; im

  • Gradle编译打包Android apk详细介绍

    Gradle编译打包Android apk详细介绍 理解Gradle构建过程,解读Android Gradle插件的配置 阅读本文一定是要使用过Gradle生成apk,文中不会讲如何安装运行Gradle,如有需要可先看文末的参考文章. APK包是一个ZIP压缩包,从Java源代码.资源文件到生成这个APK,经过了编译打包一系列特定的过程,SDK文档(/docs/tools/building/index.html)中找到.而这一系列特定的过程,重复繁琐,构建工具(build tool)就是来流程化

  • Android超详细介绍自定义多选框与点击按钮跳转界面的实现

    总程:在avtivity_main.xml设计5个控件,btn1-5,点击btn1弹出一个多选对话框,点击按钮btn1弹出一个多选框可选择你喜欢的打野英雄,点击btn2跳转到activity_main2界面(就是图片,不可选择)设计思路流程:在activity_main.xml布局界面,总体在头目录进行垂直排列,然后镶嵌5个水平的线性布局(左是ImageView,右边是Button按钮)由于5张图的大小在一个屏幕显示不出来,所以添加一个ScoveView滚动,以使所有资源可以看到! 在MainA

  • android AsyncTask详细介绍

    AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程. 使用的优点: 简单,快捷 过程可控 使用的缺点: 在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来. 2 )Handler异步实现的原理和适用的优缺点 在Handler 异步实现时,涉及到

  • Android Loader详细介绍及实例代码

    一,Android装载器基本方法 装载器从android3.0开始引进.它使得在activity或fragment中异步加载数据变得简单.装载器具有如下特性: 它们对每个Activity和Fragment都有效. 他们提供了异步加载数据的能力. 它们监视数据源的一将一动并在内容改变时传送新的结果. 当由于配置改变而被重新创建后,它们自动重连到上一个加载器的游标,所以不必重新查询数据. 装载器API概述 在使用装载器时,会涉及很多类和接口们,我们在下表中对它们总结一下: Class/Interfa

  • Android ADB详细介绍及用法

    Android ADB 用法 adb  全称是 Android Debug Bridge, 就是起到调试桥的作用. 用来操作android设备的 阅读目录 adb 有什么用 adb 下载 adb devices adb install  (安装软件) adb uninstall (卸载软件) adb shell (登录shell) adb push (从电脑上发送文件到设备) adb pull (下载文件到电脑) adb help (显示帮助信息) adb 有什么用 借助adb工具, 我们可以管

  • Android  ADB详细介绍及用法

    Android ADB 用法 adb  全称是 Android Debug Bridge, 就是起到调试桥的作用. 用来操作android设备的 阅读目录 adb 有什么用 adb 下载 adb devices adb install  (安装软件) adb uninstall (卸载软件) adb shell (登录shell) adb push (从电脑上发送文件到设备) adb pull (下载文件到电脑) adb help (显示帮助信息) adb 有什么用 借助adb工具, 我们可以管

  • Android中卡顿优化布局详细介绍

    目录 背景 实践过程 如何渲染界面 什么是过度绘制 如何查看绘制维度 界面优化 硬件加速原理 总结 背景 在当下移动互联网后半场,手机已经是人手必备的设备.App是离用户最近的应用,界面又是最直观影响用户体验的关键部分,其流畅度直接影响用户对产品的评价和留存. 技术是服务于人的,如果技术无法给你带来良好的体验,那技术本身的存在就具有争议. 所以界面性能是至关重要的,不可忽视. 实践过程 布局代码是最基础的,但也是最重要的. 首先我们看个简单小案例 不同深浅的颜色来表示过度绘制: 没颜色:没有过度

  • Android手机信号强度检测详细介绍

    最近到处在跑着找工作,难免在面试过程中遇到这样那样的问题,记得最清楚一次在面试过程中被问到,当手机处于弱网状态下,如何处理,如何监听网络信号强度变化.但是真是蒙了,回答的乱七八糟,思路一点都不明确.今天小编在这里带领大家了解下关于手机信号强度的相关几个概念. Android手机信号强度介绍 android定义了2种信号单位:dBm和asu.它们之间的关系是:dBm =-113+2asu,这是google给android手机定义的特有信号单位.例如,我的信号强度为-53dBm,则对应30asu,因

  • Android通过ksoap2传递复杂数据类型及CXF发布的webservice详细介绍

    Android通过ksoap2传递复杂数据类型及CXF发布的webservice详细介绍 最近在学校搞点东西,搞了2天的webservice,心累呀,今天中午和小伙伴终于弄通了,感觉就是一些细节问题没有注意到,啊,我的时间呀,进这么过去了,为了不让小伙伴们走弯路,我还是认真的把开发文档写一遍吧! 首先,如果我们要用CXF发布webservice用自定义类型的对象来当参数传递的话,我们应该先把这个类序列化一遍,下面就是我测试的代码,我创建了一个TGrade类,实现了KvmSerializable接

随机推荐