版权声明:本文为 宇不语 原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35064774/article/details/52644915
如有转载,请申明:
转载至 http://blog.csdn.net/qq_35064774/article/details/52644915
安卓中提供了非常多的图像和图像处理api,这里我总结了一些常用的操作。
大图片加载
在安卓中要把图片显示到界面上,需要把图片解析成Bitmap,然后设置到ImageView。
解析的图片是比较耗费内存的,尤其是大图片,比如1920*1080的图片。
如果不加做任何处理直接加载大图片,很可能会出现OOM(内存溢出),倒不是说连一张几M的图片都放不下,而是可能没有连续的足够大一块内存。
加载图片的时候,我们可以设置采样率,你可以理解为把图片”缩小加载”, 这样可以减少内存的使用。
由于手机屏幕的分辨率一般都不是很大,当图片比屏幕大的时候,就需要设置采样率压缩加载图片,降低内存的使用。
/**
* 加载图片到iv中
*/
private void loadImage() {
// 直接这样加载大图片容易导致内容溢出out of memory,对于大图速度也很慢
// Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
// 对于大图,需要进行采样率计算,其实也就是对图片缩放显示
// 获取屏幕大小
DisplayMetrics metrics = getResources().getDisplayMetrics();
// 获取图片大小
Size imgSize = getSizeWithNoDecode(getResources(), R.drawable.bg);
// 计算缩放
int scale = calculateScale(imgSize, new Size(metrics.widthPixels, metrics.heightPixels));
// 缩放加载位图
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg, opts);
iv.setImageBitmap(bitmap);
}
/**
* 根据图片尺寸和视图尺寸计算缩放率
* @param imgSize 图片尺寸
* @param viewSize 视图尺寸
* @return 缩放率,缩放大小四舍五入,大于1表示图片更大,要把图片缩小
*/
public int calculateScale(Size imgSize, Size viewSize) {
// 图片比视图小,不缩放
if(viewSize.getWidth() >= imgSize.getWidth() && viewSize.getHeight() >= imgSize.getHeight()) {
return 1;
}
int widthScale = Math.round(imgSize.getWidth() * 1.0f / viewSize.getWidth());
int heightScale = Math.round(imgSize.getHeight() * 1.0f / viewSize.getHeight());
return (int)Math.round( Math.sqrt(widthScale * widthScale + heightScale * heightScale) );
}
/**
* 在不加载图片的前提下获取图片宽高
* @param res
* @param id
* @return
*/
private Size getSizeWithNoDecode(Resources res, int id) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, id, options);
return new Size(options.outWidth, options.outHeight);
}
public final class Size {
private final int mWidth;
private final int mHeight;
/**
* Create a new immutable Size instance.
*
* @param width The width of the size, in pixels
* @param height The height of the size, in pixels
*/
public Size(int width, int height) {
mWidth = width;
mHeight = height;
}
/**
* Get the width of the size (in pixels).
* @return width
*/
public int getWidth() {
return mWidth;
}
/**
* Get the height of the size (in pixels).
* @return height
*/
public int getHeight() {
return mHeight;
}
}
图像操作
缩放
/**
* 将图片缩小一半绘制到控件
*/
private void scaleHalf() {
// 准备图片
Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 准备画笔
Paint paint = new Paint();
// 准备矩阵规则
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f);
// 绘制
canvas.drawBitmap(srcBitmap, matrix, paint);
// 设置图片到控件
ivDest.setImageBitmap(bitmap);
}
旋转
/**
* 使图片旋转绘制
*/
private void rotation() {
// 准备图片
Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 准备变换矩阵
Matrix matrix = new Matrix();
matrix.setRotate(30, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
// 绘制
canvas.drawBitmap(srcBitmap, matrix, new Paint());
// 设置图片
ivDest.setImageBitmap(bitmap);
}
位移
/**
* 图片平移
*/
private void shift() {
// 准备图片
Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 准备变化矩阵
Matrix matrix = new Matrix();
// 平移操作
matrix.setTranslate(50, 50);
// 绘制
canvas.drawBitmap(srcBitmap, matrix, new Paint());
// 设置图片
ivDest.setImageBitmap(bitmap);
}
翻转
/**
* 图片翻转
*/
private void overturn(boolean isX) {
// 准备图片
Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 准备矩阵
Matrix matrix = new Matrix();
// 翻转
if (isX)
matrix.setScale(-1, 1, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
else
matrix.setScale(1, -1, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
// 绘制
canvas.drawBitmap(srcBitmap, matrix, new Paint());
// 设置图片
ivDest.setImageBitmap(bitmap);
}
改变RGB颜色值(调节色相)
/**
* 调整图片rgb的通道值,并显示到控件。参数范围0-2。1表示不改变原颜色值,值越大表示该颜色越明显
*
* @param red
* @param green
* @param blue
*/
private void regulateHueAndShow(float red, float green, float blue) {
// 准备图片
Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 准备画笔
Paint paint = new Paint();
// 设置画笔颜色值
float[] cm = {
1 * red, 0, 0, 0, 0,
0, 1 * green, 0, 0, 0,
0, 0, 1 * blue, 0, 0,
0, 0, 0, 1, 0
};
paint.setColorFilter(new ColorMatrixColorFilter(cm));
// 绘制
canvas.drawBitmap(srcBitmap, new Matrix(), paint);
// 显示
ivDest.setImageBitmap(bitmap);
}
图形绘制
/**
* 创建合适视图大小的图片
* @return
*/
private Bitmap createSuitableSizeBitmap() {
Bitmap bitmap = Bitmap.createBitmap(iv.getWidth(), iv.getHeight(), Bitmap.Config.RGB_565);
// 绘制背景
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
canvas.drawRect(0, 0, iv.getWidth(), iv.getHeight(), paint);
return bitmap;
}
画笔
/**
* 确定修改画笔配置
*/
private void ok() {
// stroke 是否空心
if (cbStroke.isChecked()) {
paint.setStyle(Paint.Style.STROKE);
} else {
paint.setStyle(Paint.Style.FILL);
}
// anti alias 抗锯齿
paint.setAntiAlias(cbAntiAlias.isChecked());
// color 颜色
paint.setColor(Color.parseColor(etColor.getText().toString().trim()));
Toast.makeText(DrawOperatorActivity.this, "修改成功,重绘后可以看到效果", Toast.LENGTH_SHORT).show();
}
线
/**
* 画线
*/
private void drawLine() {
// 准备图片
Bitmap bitmap = createSuitableSizeBitmap();
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 绘制
canvas.drawLine(50, 50, 100, 100, paint);
// 设置图片
iv.setImageBitmap(bitmap);
}
圆
/**
* 画圆
*/
private void drawCircle() {
// 准备图片
Bitmap bitmap = createSuitableSizeBitmap();
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 绘制
canvas.drawCircle(200, 200, 100, paint);
// 设置图片
iv.setImageBitmap(bitmap);
}
矩形
/**
* 画矩形
*/
private void drawRect() {
// 准备图片
Bitmap bitmap = createSuitableSizeBitmap();
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 绘制
canvas.drawRect(50, 50, 300, 300, paint);
// 设置图片
iv.setImageBitmap(bitmap);
}
扇形
/**
*
* 画扇形
*/
private void drawSector() {
// 准备图片
Bitmap bitmap = createSuitableSizeBitmap();
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 绘制
canvas.drawArc(new RectF(50, 50, 300, 300), 0, 120, true, paint);
// 设置图片
iv.setImageBitmap(bitmap);
}
多边形
/**
* 画多边形
*/
private void drawPolygon() {
// 准备图片
Bitmap bitmap = createSuitableSizeBitmap();
// 准备画布
Canvas canvas = new Canvas(bitmap);
// 绘制
Path path = new Path();
path.moveTo(180, 300);
path.lineTo(220, 300);
path.lineTo(200, 50);
path.lineTo(180, 300);
path.arcTo(new RectF(180, 280, 220, 320), 0, 180);
canvas.drawPath(path, paint);
// 设置图片
iv.setImageBitmap(bitmap);
}