Android|Android Canvas和Bitmap结合绘图详解流程
目录
- Rect/RectF
- Matrix
- Canvas
- Bitmap
Rect/RectF 存储四个值的矩形类:左侧、顶部、右侧和底部。可用于直接在画布上绘制或仅用于存储要绘制的对象的大小。Rect和RectF类之间的区别在于 RectF 存储浮点值,而Rect类存储整数。
private static Bitmap createDrawableBitmap(Drawable drawable) {int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); if (width <= 0 || height <= 0) {return null; }float scale = Math.min(1.0f, ((float) MAX_IMAGE_SIZE) / ((float) (width * height))); if ((drawable instanceof BitmapDrawable) && scale == 1.0f) {return ((BitmapDrawable) drawable).getBitmap(); }int bitmapWidth = (int) (((float) width) * scale); int bitmapHeight = (int) (((float) height) * scale); Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Rect existingBounds = drawable.getBounds(); int left = existingBounds.left; int top = existingBounds.top; int right = existingBounds.right; int bottom = existingBounds.bottom; drawable.setBounds(0, 0, bitmapWidth, bitmapHeight); drawable.draw(canvas); drawable.setBounds(left, top, right, bottom); return bitmap; }
Matrix 一个3 x 3的矩阵,用于存储可用于转换画布的信息。矩阵可以存储以下类型的变换信息:缩放、倾斜、旋转、平移。而每种变换方式都对应着三种方法:set方法将用新值替换当前的Matrix,不管之前Matrix的值是什么。pre和post 方法将在当前Matrix包含的任何内容之前或之后应用新的转换。
Matrix m = new Matrix(); m.setRotate(90); m.setScale(3f,1f); m.setTranslate(200, 200);
【Android|Android Canvas和Bitmap结合绘图详解流程】只有平移,旋转值和缩放值被重置
Matrix m = new Matrix(); m.preScale(3f,1f); m.preTranslate(200f, 100f); m.postScale(0.5f, 1f); m.postTranslate(100f, 0f);
先进行平移(200f, 100f),然后进行缩放(3f, 1f),然后进行缩放(0.5f, 1f),最后进行平移(100f, 0f)
Matrix m = new Matrix(); m.postTranslate(200f, 0f); m.preScale(0.5f, 1f); m.setScale(1f, 1f); m.postScale(5f, 1f); m.preTranslate(200f, 100f);
先进行平移(200f, 100f),然后进行缩放(1f, 1f),最后进行缩放(5f, 1f)。因为用了set方法所以平移(200f, 0f)和缩放(0.5f, 1f)被覆盖,不起作用
假如先进行平移(x, y),再进行缩放(sx, sy),那么看到的平移效果等同于(x*sx, y*sy),因为缩放是将整个画布或者坐标系进行缩放的
Canvas Canvas相当于Android的画布,可以把画布想象成一块内存空间,也就是一个Bitmap。Canvas的API提供一整套在这个Bitmap上进行绘图的操作方法。
- drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
- drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)
- drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)
Bitmap background = Bitmap.createBitmap((int)width, (int)height, Config.ARGB_8888); float originalWidth = originalImage.getWidth(); float originalHeight = originalImage.getHeight(); Canvas canvas = new Canvas(background); float scale = width / originalWidth; float xTranslation = 0.0f; float yTranslation = (height - originalHeight * scale) / 2.0f; Matrix transformation = new Matrix(); transformation.postTranslate(xTranslation, yTranslation); transformation.preScale(scale, scale); Paint paint = new Paint(); paint.setFilterBitmap(true); canvas.drawBitmap(originalImage, transformation, paint);
矩形区域示例:
public Bitmap cropCircle(Bitmap bitmap) {Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,bitmap.getWidth()/2, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; }
Bitmap 位图,点阵图,可以理解为int[] buffer,用来存储每个像素点的容器。
- Bitmap.createBitmap(int width, int height, Bitmap.Config config)
- Bitmap.createBitmap(Bitmap src)
- Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)
- Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter)
- BitmapFactory.decodeByteArray(byte[] data, int offset, int length, BitmapFactory.Options opts)
- BitmapFactory.decodeFile(String pathName, Options opts)
- BitmapFactory.decodeStream(InputStream is, Rect outPadding,Options opts)
public Bitmap transform(Bitmap source) {int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size); if (squaredBitmap != source) {source.recycle(); }Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); Canvas canvas = new Canvas(bitmap); Paint avatarPaint = new Paint(); BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); avatarPaint.setShader(shader); Paint outlinePaint = new Paint(); outlinePaint.setColor(Color.WHITE); outlinePaint.setStyle(Paint.Style.STROKE); outlinePaint.setStrokeWidth(STROKE_WIDTH); outlinePaint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, avatarPaint); canvas.drawCircle(r, r, r - STROKE_WIDTH / 2, outlinePaint); squaredBitmap.recycle(); return bitmap; }
BitmapFactory生成示例:
private static Bitmap decodeSampledBitmapFromUrl(String url, int reqWidth, int reqHeight) throws IOException {// First decode with inJustDecodeBounds=true to check dimensionsfinal Options options = new Options(); options.inJustDecodeBounds = true; InputStream stream = fetchStream(url); BitmapFactory.decodeStream(stream, null, options); stream.close(); // Calculate inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize setoptions.inJustDecodeBounds = false; stream = fetchStream(url); Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options); stream.close(); return bitmap; } private static InputStream fetchStream(String urlString) throws IllegalStateException, IOException {DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet request = new HttpGet(urlString); HttpResponse response = httpClient.execute(request); return response.getEntity().getContent(); } private static int calculateInSampleSize(Options options, int reqWidth, int reqHeight) {// Raw height and width of imagefinal int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) {// Calculate ratios of height and width to requested height and widthfinal int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee// a final image with both dimensions larger than or equal to the// requested height and width.inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; }return inSampleSize; }
注意:通过Bitmap.createBitmap生成的Bitmap对象是可变对象,可以向Bitmap上绘制内容,而通过BitmapFactory生成的Bitmap对象必须指定BitmapFactory.Options.inMutable = true,否则就是不可变对象,不能向上面绘制内容。
感谢大家的支持,如有错误请指正,如需转载请标明原文出处!
到此这篇关于Android Canvas和Bitmap结合绘图详解流程的文章就介绍到这了,更多相关Android 绘图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 急于表达——往往欲速则不达
- 第三节|第三节 快乐和幸福(12)
- android第三方框架(五)ButterKnife
- 20170612时间和注意力开销记录
- 2.6|2.6 Photoshop操作步骤的撤消和重做 [Ps教程]
- 对称加密和非对称加密的区别
- 眼光要放高远
- 樱花雨
- 前任
- 2020-04-07vue中Axios的封装和API接口的管理