保存涂抹区域的图片_升级版
来源:互联网 发布:mac ps安装失败 编辑:程序博客网 时间:2024/04/29 09:11
还是有空截张图,给大家看看效果,效果展示的是涂抹区域进行文字识别,然后进行百度翻译的一种演示
上次写了一篇关于涂抹图片保存本地的view,后来实际测试中发现一个问题,就是不同的手机拍照显示不同的大小,这就尴尬了 ,高像素的手机显示图片太大,界面显示不齐全,低像素的手机图片也不能铺满屏幕 ,这个问题就涉及到图片的压缩与拉伸,这里优化一下以前的代码
原文地址 :http://blog.csdn.net/fkgjdkblxckvbxbgb/article/details/76649928
有希望了解原理的卓友可以去看上次写的那一篇博文 ,这里贴源码,主要是屏幕适配以及图片的压缩
图片压缩的类,因为照相机拍照的比例是4:3,我这里就直接按照4:3的比例进行压缩
package com.reeman.ringtranslate.util.image;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class ImageSizeUtil { /*** * 读取图片资源 * @param reqWidth * @return */ public static Bitmap decodeSampleBitmap(String picPath, int reqWidth) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; //去加载图片 BitmapFactory.decodeFile(picPath, options); options.inSampleSize = calculateImSampleSize(options, reqWidth); options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(picPath, options); } /*** * 计算图片的压缩比例 * @param options * @param reqWidth * @return */ private static int calculateImSampleSize(BitmapFactory.Options options, int reqWidth) { int reqHeight = reqWidth * 4 / 3; if (reqWidth == 0) { return 1; } int height = options.outHeight; int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || reqWidth > reqWidth) { int halfWidth = width / 2; int halfHeight = height / 2; while ((halfHeight / inSampleSize) >= reqHeight || (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; //压缩过的图片比例比控件大,再次缩减压缩比例 } } return inSampleSize; }}
涂抹区域的代码我
修正了一些部分,在每次重绘之前,都清掉以前的轨迹,就在OnTouch-MothionEventDown里面。见代码
package com.reeman.ringtranslate.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.os.Environment;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import com.reeman.ringtranslate.domain.TouchPoint;import com.reeman.ringtranslate.util.image.ImageSizeUtil;import com.reeman.ringtranslate.util.SharedPerManager;import java.io.File;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.Collections;import java.util.List;public class XfermodeView extends View { public static final String TEMP_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/reeman/ringTranslate/picture/temp.jpg"; private Bitmap mBgBitmap; Bitmap mFgBitmap; private Paint mPaint; private Canvas mCanvas; private Path mPath; int FINGER_WIDTH = 40; int BLACK_HALF_COLOR = 0x89000000; public XfermodeView(Context context) { this(context, null); } public XfermodeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public XfermodeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBgBitmap, 0, 0, null); canvas.drawBitmap(mFgBitmap, 0, 0, null); } private void init() { mPaint = new Paint(); mPaint.setAlpha(0); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeWidth(100); mPaint.setStrokeCap(Paint.Cap.ROUND); mPath = new Path(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: listener.onEvent(MotionEvent.ACTION_DOWN); listPoint.clear(); listPoint.add(new TouchPoint(event.getX(), event.getY())); clearCanvas(); mPath.reset(); invalidate(); mPath.moveTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: listener.onEvent(MotionEvent.ACTION_MOVE); listPoint.add(new TouchPoint(event.getX(), event.getY())); mPath.lineTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: listener.onEvent(MotionEvent.ACTION_UP); listPoint.add(new TouchPoint(event.getX(), event.getY())); changePoints(); break; } mCanvas.drawPath(mPath, mPaint); invalidate(); return true; } public void clearCanvas() { if (mPaint == null || mCanvas == null) { return; } mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mCanvas.drawPaint(mPaint); mCanvas = new Canvas(mFgBitmap); mCanvas.drawColor(BLACK_HALF_COLOR); invalidate(); } List<TouchPoint> listPoint = new ArrayList<>(); List<Float> pointX = new ArrayList<>(); List<Float> pointY = new ArrayList<>(); /*** * 计算手指滑动的区域 */ private void changePoints() { pointX.clear(); pointY.clear(); for (int i = 0; i < listPoint.size(); i++) { pointX.add(listPoint.get(i).getPointX()); pointY.add(listPoint.get(i).getPointY()); } /*** * 这里因为用户会反复的涂抹,所以吧所有的移动点添加到集合中,然后对所有的点取值 * 取出手指的最大范围和最小范围, */ float minX = Collections.min(pointX); float minY = Collections.min(pointY); float maxX = Collections.max(pointX); float maxY = Collections.max(pointY); /*** * 这里加上笔触的宽度 */ minX = minX - FINGER_WIDTH; minY = minY - FINGER_WIDTH; maxX = maxX + FINGER_WIDTH; maxY = maxY + FINGER_WIDTH; if (minX < 0) { minX = 0; } if (minY < 0) { minY = 0; } if (maxX > SharedPerManager.getWidth()) { maxX = SharedPerManager.getWidth(); } if (maxY > SharedPerManager.getHeight()) { maxY = SharedPerManager.getHeight(); } //这是手指绘制的区域 RectF rect = new RectF(minX, minY, maxX, maxY); saveBitmap(rect); } /*** * 保存图片到本地 * @param rect */ private void saveBitmap(RectF rect) { try { Log.i("point", "====保存的尺寸==" + rect.left + "/" + rect.top + " ///" + rect.right + "/" + rect.bottom); float rectWidth = Math.abs(rect.left - rect.right); float rectHeight = Math.abs(rect.top - rect.bottom); Log.i("point", "====保存的面积==" + rectWidth * rectHeight); if (rectWidth * rectHeight < 6500) { listener.touchCutError("涂抹区域太小"); return; } Bitmap bmp = Bitmap.createBitmap((int) rect.width(), (int) rect.height(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmp); canvas.translate(-(rect.left), -(rect.top)); canvas.drawColor(Color.WHITE); canvas.drawBitmap(mBgBitmap, 0, 0, null); canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); File file = new File(TEMP_PATH); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } if (!file.exists()) { file.createNewFile(); } FileOutputStream fos = new FileOutputStream(file.getPath()); bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.close(); listener.touchBackUrl(file.getPath()); } catch (Exception e) { listener.touchCutError(e.toString()); e.printStackTrace(); } } public void setBitmap(String path) { mBgBitmap = ImageSizeUtil.decodeSampleBitmap(path, SharedPerManager.getWidth()); mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mFgBitmap); mCanvas.drawColor(BLACK_HALF_COLOR); invalidate(); } TouchCutListener listener; public void setOnTouchCutListener(TouchCutListener listener) { this.listener = listener; } public interface TouchCutListener { void onEvent(int event); void touchBackUrl(String filePath); void touchCutError(String error); }}
主界面的代码
1:初始化代码
@BindView(R.id.as_modeview)XfermodeView mModeview;
2:设置图片地址
Modeview.setBitmap(mPath);
阅读全文
0 0
- 保存涂抹区域的图片_升级版
- canvas 对图片进行涂抹,涂抹区域保存图片存入本地
- android 裁剪涂抹区域并保存成图片
- 截取指定区域的并保存图片
- 保存图片感兴趣区域
- 利用HTML5d的Canvas绘制签名区域,保存为图片
- VC将屏幕区域保存为图片
- 将控件区域保存为BMP图片
- OpenCV编程->ROI区域保存为图片
- Opencv: 将一张图片的部分区域保存成另一张图片
- H5中实现图片的涂抹擦除--利用jquery.eraser.js插件
- iOS图片处理之涂抹马赛克解析
- 开发案例3——保存指定区域的图片的相机
- 图片的热点区域
- C#控制台程序中使用剪贴板将Excel的单元格区域保存为图片
- [wxWidgets]_[中级]_[使用wxRendererNative画的原生图片生成带alpha透明区域的wxBitmap]
- CPU硅胶的正确使用涂抹方法
- iOS _ 图片保存到本地相册
- jquery-ui.min.js 插件
- Bigtable: A Distributed Storage System for Structured Data : part8 Real Applications
- input多文件上传
- java参数传递
- 数据结构-优先级队列
- 保存涂抹区域的图片_升级版
- EasyUi的总结
- Laravel 数据库
- jquery.growl.js 插件
- 巧用Linux命令完成统计排序功能yes2
- stl-list
- MATLAB编程笔记
- 音乐的调节
- 背包问题(深度优先搜索解法)