Android 图片处理(Canvas/Paint/Matrix/Path/Bezier曲线)
本文由 Luzhuo 编写,转发请保留该信息.
原文: https://blog.csdn.net/Rozol/article/details/79683220
加载图片
将图片加载到内存显示之前, 要先根据将要显示的容器的大小来按比例压缩图片, 这样才不至于将内存撑爆.
/**
* 加载图片
* <br>步骤: 获取手机和图片分辨率 -> 计算缩放比 -> 加载图片(用最大的缩放比)
*/
public void onclick(View view){
// 获取手机分辨率
DispalyHW screenHW = getScreenHeightWidth(this);
Log.i(TAG, "手机分辨率: width: " + screenHW.width + " height: " + screenHW.height);
// 获取图片分辨率
File file = new File(Environment.getExternalStorageDirectory(), "dog.jpg");
DispalyHW imageHW = getImageHeightWidth(file);
Log.i(TAG, "图片分辨率: width: " + imageHW.width + " height: " + imageHW.height);
// 计算缩放比: 图片宽高 ÷ 手机宽高 的比率, 取最大的缩放比
int scale = 1;
int scalex = imageHW.width / screenHW.width;
int scaley = imageHW.height / screenHW.height;
if (scalex >= scaley && scalex > scale) {
scale = scalex;
}
if (scaley > scalex && scaley > scale) {
scale = scaley;
}
Log.i(TAG, "缩放比为: " + scale);
// 加载图片
Bitmap bitmap = getBitmap(file, scale);
imageView.setImageBitmap(bitmap);
}
获取手机分辨率
/** * 获取手机分辨率 * @param context */ public static DispalyHW getScreenHeightWidth(Context context){ DispalyHW hw = new DispalyHW(); WindowManager wm = (WindowManager) context.getSystemService(WINDOW_SERVICE); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) { hw.width = wm.getDefaultDisplay().getWidth(); hw.height = wm.getDefaultDisplay().getHeight(); } else { // api>13 Point point = new Point(); wm.getDefaultDisplay().getSize(point); hw.width = point.x; hw.height = point.y; } return hw; }
获取图片分辨率
/** * 获取图片的分辨率率 * @param file 图片文件 * @return 如果文件不存在返回null */ public static DispalyHW getImageHeightWidth(File file){ if (!file.exists()) return null; DispalyHW hw = new DispalyHW(); // bitmap工厂的配置参数 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 加载图片信息, 不加载图片 BitmapFactory.decodeFile(file.getAbsolutePath(), options); // 获取图片的宽和高 hw.width = options.outWidth; hw.height = options.outHeight; return hw; }
加载图片
/** * 加载图片 * @param file 图片文件 * @param scale 缩放比 >= 1 * @return 文件不存在返回null */ public static Bitmap getBitmap(File file, int scale){ if (!file.exists()) return null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = scale; // 按缩放比压缩 options.inJustDecodeBounds = false; // 加载图片 Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options); return bitmap; }
图片处理
只能对副本图片进行处理
创建副本
public void onclick(View view){
// 从资源加载Bitmap
Bitmap srcBitmap = getBitmapOnRes(this, R.mipmap.abc);
iv_src.setImageBitmap(srcBitmap);
// 创作模板
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
Canvas canvas = new Canvas(copyBitmap); // 画布
Paint paint = new Paint(); // 画笔
Matrix matrix = new Matrix(); // 矩阵
canvas.drawBitmap(srcBitmap, matrix, paint); // 绘画
iv_copy.setImageBitmap(copyBitmap);
}
从资源加载图片
/** * 从资源文件中加载图片 * @param context 上下文 * @param drawableID 资源图片id */ public static Bitmap getBitmapOnRes(Context context, @DrawableRes int drawableID){ Bitmap resBitmap = BitmapFactory.decodeResource(context.getResources(), drawableID); return resBitmap; }
画布
/**
* 对画布Canvas进行操作, 画布具有 移动, 状态保存与恢复, 绘制等操作
*/
public void onclick(View view){
Bitmap srcBitmap = getBitmapOnRes(this, R.mipmap.abc);
iv_src.setImageBitmap(srcBitmap);
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth() * 3, srcBitmap.getHeight() * 3, srcBitmap.getConfig());
Paint paint = new Paint(); // 画笔
paint.setStyle(Paint.Style.STROKE); // 只画线不填充
Matrix matrix = new Matrix(); // 矩阵
Path path = new Path(); // 路径
path.moveTo(10, 50);
path.lineTo(30, 100);
path.lineTo(60, 300);
path.close();
Canvas canvas = new Canvas(copyBitmap); // 画布
// --- 效果叠加 ---
// 平移(参数: x, y)
canvas.translate(10, 10);
// 缩放(参数: 缩放倍数, x, y)
canvas.scale(0.5f, 0.5f, srcBitmap.getWidth() / 2, srcBitmap.getHeight() / 2);
// 旋转(参数: 角度, x, y)
canvas.rotate(30, srcBitmap.getWidth() / 2, srcBitmap.getHeight() / 2);
// --- 画布操作动作的保存与恢复 (仅对 平移等操作有效, 对绘制操作无效) ---
// 保存画布修改状态
int save = canvas.save();
// 还原到最近保存的状态
// canvas.restore();
// 还原到指定状态
canvas.restoreToCount(save);
// --- 绘制 ---
// 绘制点(参数: x,y / [x,y,x,y,x,y])
canvas.drawPoint(10, 10, paint);
canvas.drawPoints(new float[]{
11, 11, 12, 11