欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Canvas和Bitmap結(jié)合繪圖詳解流程

 更新時間:2021年11月02日 17:21:53   作者:折翅鵬  
在 Android Canvas 上繪圖非常難,在繪圖時需要理解許多不同的類和概念。這篇文章中,將介紹 Android 框架中可用的一些類,它們可以讓畫布使用時更輕松

Rect/RectF

存儲四個值的矩形類:左側(cè)、頂部、右側(cè)和底部??捎糜谥苯釉诋嫴忌侠L制或僅用于存儲要繪制的對象的大小。Rect和RectF類之間的區(qū)別在于 RectF 存儲浮點值,而Rect類存儲整數(shù)。

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的矩陣,用于存儲可用于轉(zhuǎn)換畫布的信息。矩陣可以存儲以下類型的變換信息:縮放、傾斜、旋轉(zhuǎn)、平移。而每種變換方式都對應(yīng)著三種方法:set方法將用新值替換當前的Matrix,不管之前Matrix的值是什么。pre和post 方法將在當前Matrix包含的任何內(nèi)容之前或之后應(yīng)用新的轉(zhuǎn)換。

Matrix m = new Matrix();
m.setRotate(90);
m.setScale(3f,1f);
m.setTranslate(200, 200);

只有平移,旋轉(zhuǎn)值和縮放值被重置

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的畫布,可以把畫布想象成一塊內(nèi)存空間,也就是一個Bitmap。Canvas的API提供一整套在這個Bitmap上進行繪圖的操作方法。

  • drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

使用指定的矩陣繪制位圖,繪制的時候會使用矩陣進行變換,矩陣和畫筆可以傳入空值

  • drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)

將傳入的源圖bitmap指定的矩形區(qū)域src繪制到目標矩形區(qū)域dst中,如果矩形區(qū)域src傳入空值,則表示繪制整個源圖到目標矩形區(qū)域dst中,繪制的時候源圖或子集自動縮放/平移以填充目標矩形。如果繪制對應(yīng)的畫筆通過方法setMaskFilter指定了超出原始位圖寬/高的掩碼過濾器(如BlurMaskFilter),則會位圖將繼續(xù)被繪制,就像在具有CLAMP模式的著色器中一樣。因此,原始寬/高之外的顏色將是復制的邊緣顏色。因為源矩形區(qū)域src對應(yīng)的坐標空間是相對于源圖的,而目標矩形區(qū)域dst對應(yīng)的坐標空間是繪制視圖對應(yīng)的坐標空間,因此要控制好對應(yīng)的縮放因子。

  • 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);

矩形區(qū)域示例:

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)

createBitmap生成示例:

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 dimensions
	    final Options options = new Options();
	    options.inJustDecodeBounds = true;
	    
	    InputStream stream = fetchStream(url);
	    BitmapFactory.decodeStream(stream, null, options);
	    stream.close();

	    // Calculate inSampleSize
	    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
	    // Decode bitmap with inSampleSize set
	    options.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 image
		final 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 width
			final 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上繪制內(nèi)容,而通過BitmapFactory生成的Bitmap對象必須指定BitmapFactory.Options.inMutable = true,否則就是不可變對象,不能向上面繪制內(nèi)容。

感謝大家的支持,如有錯誤請指正,如需轉(zhuǎn)載請標明原文出處!

到此這篇關(guān)于Android Canvas和Bitmap結(jié)合繪圖詳解流程的文章就介紹到這了,更多相關(guān)Android 繪圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android使用線程更換壁紙

    Android使用線程更換壁紙

    這篇文章主要為大家詳細介紹了Android使用線程更換壁紙的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Android實現(xiàn)粒子中心擴散動畫效果

    Android實現(xiàn)粒子中心擴散動畫效果

    粒子動畫效果相比其他動畫來說是非常復雜了的,主要涉及三個方面,粒子初始化、粒子位移、粒子回收等問題,本篇將實現(xiàn)兩種動畫效果,代碼基本相同,只是旋轉(zhuǎn)速度不一樣,需要的朋友可以參考下
    2024-02-02
  • Android編程實現(xiàn)獲取新浪天氣預報數(shù)據(jù)的方法

    Android編程實現(xiàn)獲取新浪天氣預報數(shù)據(jù)的方法

    這篇文章主要介紹了Android編程實現(xiàn)獲取新浪天氣預報數(shù)據(jù)的方法,涉及Android基于新浪接口的調(diào)用及數(shù)據(jù)處理技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • Flutter listview如何實現(xiàn)下拉刷新上拉加載更多功能

    Flutter listview如何實現(xiàn)下拉刷新上拉加載更多功能

    這篇文章主要給大家介紹了關(guān)于Flutter listview如何實現(xiàn)下拉刷新上拉加載更多功能的相關(guān)資料,對于新聞列表數(shù)據(jù)的更新和加載更多是必不可少的,而實現(xiàn)下拉刷新與上劃加載更多的方式有很多種,需要的朋友可以參考下
    2021-08-08
  • android實現(xiàn)給未簽名的apk簽名方法

    android實現(xiàn)給未簽名的apk簽名方法

    下面小編就為大家?guī)硪黄猘ndroid實現(xiàn)給未簽名的apk簽名方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • Adnroid打造通用的帶進度條的WebView

    Adnroid打造通用的帶進度條的WebView

    這篇文章主要為大家詳細介紹了Adnroid打造通用的帶進度條的WebView的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • android開發(fā)教程之實現(xiàn)toast工具類

    android開發(fā)教程之實現(xiàn)toast工具類

    這篇文章主要介紹了android開發(fā)中需要的toast工具類,需要的朋友可以參考下
    2014-05-05
  • android實現(xiàn)簡易登錄注冊界面及邏輯設(shè)計

    android實現(xiàn)簡易登錄注冊界面及邏輯設(shè)計

    這篇文章主要為大家詳細介紹了android實現(xiàn)簡易登錄注冊界面及邏輯設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • android 震動和提示音的實現(xiàn)代碼

    android 震動和提示音的實現(xiàn)代碼

    這篇文章主要介紹了android 震動和提示音的實現(xiàn)代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • ExpandableListView實現(xiàn)二級列表購物車

    ExpandableListView實現(xiàn)二級列表購物車

    這篇文章主要為大家詳細介紹了ExpandableListView實現(xiàn)二級列表購物車,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11

最新評論