Android Bitmap详细介绍(3)
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;
}
}
Android Bitmap详细介绍(3)的更多相关文章
- Android Bitmap详细介绍(转)
转自: Bitmap详细介绍 package com.testbitmapscale; import java.io.File; import java.io.FileInputStream; imp ...
- 1、Android Bitmap详细介绍
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io ...
- Android Bitmap详细介绍
package com.testbitmapscale; import java.io.File; import java.io.FileInputStream; import java.io.Fil ...
- Android Bitmap缓存介绍
转载自http://blog.csdn.net/linghu_java/article/details/8595717 Android中加载一个Bitmap(位图)到你的UI界面是非常简单的,但是如果 ...
- Android Application 详细介绍
一.先看看文档里怎么说 Base class for those who need to maintain global application state. You can provide your ...
- Android manifest之manifest标签详细介绍
AndroidManifest详细介绍 本文主要对AndroidManifest.xml文件中各个标签进行说明.索引如下: 概要PART--01 manifest标签PART--02 安全机制和per ...
- 学习笔记:APP切图那点事儿–详细介绍android和ios平台
学习笔记:APP切图那点事儿–详细介绍android和ios平台 转载自:http://www.woofeng.cn/articles/168.html 版权归原作者所有 作者:亚茹有李 原文地址 ...
- Android SQLite 数据库详细介绍
Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...
- 详细介绍android rom移植知识普及
详细介绍android rom移植知识普及 最近接到很多兄弟们的求助,也回答过无数个和下面这个问题类似的问题: 如何编译android 原生代码得到一个rom,然后跑到某某手机上. 鉴于很多兄弟对这块 ...
随机推荐
- UNIX 环境模拟工具Cygwin安装及使用图文教程
对于 UNIX 本身,也有各种称呼.IBM® 大型机用户说各种带字母 "z" 的行话,比如 IBM z/OS® 和 System z9 Virtual Machine (z/VM) ...
- python pep8 命令规范
命名规范:总体原则,新编代码必须按下面命名风格进行,现有库的编码尽量保持风格.1 尽量单独使用小写字母‘l’,大写字母‘O’等容易混淆的字母.2 模块命名尽量短小,使用全部小写的方式,可以使用下划线. ...
- bzoj 3218: a + b Problem【主席树+最小割】
直接建图比较显然,是(s,i,w),(i,t,b),(i,i',p),(i,j,inf),然而建出来之后发现边数是n方级别的,显然跑不过去,然后就有一种比较神的思路:把a离散了建一棵权值线段树,然后要 ...
- spoj 287 NETADMIN - Smart Network Administrator【二分+最大流】
在spoj上用题号找题就已经是手动二分了吧 把1作为汇点,k个要入网的向t连流量为1的边,因为最小颜色数等于最大边流量,所以对于题目所给出的边(u,v),连接(u,v,c),二分一个流量c,根据最大流 ...
- css设置页面全屏背景
.background { background: url(xxx.png); background-size: 100% 100%; height: 100%; position: fixed; w ...
- 【SpringCloud构建微服务系列】微服务网关Zuul
一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...
- Elasticsearch 2.3.2 安装部署
先按照http://blog.csdn.net/love13135816/article/details/51690280这个教程安装, 不过后面的IK分词器安装部分有问题. 所以中文分词器插件的安装 ...
- 在Python解释器运行程序
在解释器中运行 ***.py文件的方法:使用import添加模块 ***.py,然后调用 ***.py中的函数 例:在zoo.py中定义hours函数 运行方法: >>> impo ...
- Service官方教程(8)Bound Service示例之2-跨进程使用Messenger
Compared to AIDL When you need to perform IPC, using a Messenger for your interface is simpler than ...
- 转 Dockerfile 常用指令 - 每天5分钟玩转 Docker 容器技术(16)
是时候系统学习 Dockerfile 了. 下面列出了 Dockerfile 中最常用的指令,完整列表和说明可参看官方文档. FROM指定 base 镜像. MAINTAINER设置镜像的作者,可以是 ...