Canvas繪製Bitmap 友盟分享純圖片至微信好友
阿新 • • 發佈:2019-01-22
1.需求場景
Android
開發中,有將帶有二維碼的純圖片分享給微信需求 ,左是分享一張內容固定圖片,右是需求實現圖片
2.需求分析
- 檢視友盟開發文件
new ShareAction(ShareActivity.this).withText("hello").withMedia(image).share();
UMImage image = new UMImage(ShareActivity.this, "imageurl");//網路圖片 UMImage image = new UMImage(ShareActivity.this, file);//本地檔案 UMImage image = new UMImage(ShareActivity.this, R.drawable.xxx);//資原始檔 UMImage image = new UMImage(ShareActivity.this, bitmap);//bitmap檔案 UMImage image = new UMImage(ShareActivity.this, byte[]);//位元組流
友盟分享在分享圖片構建UMImage物件時,可以有以上的幾種形式,推薦網路圖片和資原始檔方式。我們的需求用bitmap形式作為分享最為合適,自然想到通過canvas來繪製這個bitmap物件。
- canvas 和 bitmap
網上有很多關於canvas的相關資料,canvas的其他內容就不在本篇文章中做說明,我們來看下canvas和bitmap相關的知識點。Android提供了canvas繪製點陣圖的幾個方法,大家可以根據自己需求來編寫。
2.需求實現
- 定義bitmap寬高,建立bitmap物件
private Bitmap createCanvasBitmap() { // 1.建立背景圖片bitmap Bitmap backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.background_image); // 2.計算出螢幕寬高以及設定背景圖居中的left和top值 WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); assert wm != null; screenWidth = wm.getDefaultDisplay().getWidth(); screenHeight = wm.getDefaultDisplay().getHeight(); int left = screenWidth / 2 - backgroundBitmap.getWidth() / 2; int top = screenHeight / 2 - backgroundBitmap.getHeight() / 2; // 3.建立需要的bitmap物件 並放入畫布 寬高是螢幕的寬高 Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); // 4.建立畫筆 設定相關屬性 Paint paint = new Paint(); paint.setAntiAlias(true); RectF rect = new RectF(left, top, 0, 0); canvas.drawRoundRect(rect, 100, 100, paint); paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN)); /* * 5.繪製背景圖片 * @param1:要繪製的bitmap物件 * @param2:繪製的點陣圖距離螢幕左邊的距離 * @param3:繪製的點陣圖距離螢幕頂部的距離 * @param4:畫筆 */ canvas.drawBitmap(backgroundBitmap, left, top, null); // 6.繪製標題文字(文字) drawTitleText(canvas); // 7.繪製圓形頭像(圖形) drawAvatars(canvas); // 8.繪製參加資訊(文字) drawPartText(canvas); return Bitmap.createBitmap(bitmap, left, top, backgroundBitmap.getWidth(), backgroundBitmap.getHeight()); }
- 繪製活動名稱,參與資訊文字
private void drawTitleText(Canvas canvas) { String testStr = "第三屆君戈鐵馬-教育人重走玄奘之路"; Paint mPaint = new Paint(); mPaint.setStrokeWidth(2); mPaint.setTextSize(resizeTextSize(25)); mPaint.setColor(Color.RED); mPaint.setTextAlign(Paint.Align.LEFT); Rect bounds = new Rect(); mPaint.getTextBounds(testStr, 0, testStr.length(), bounds); Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt(); // 處理字型垂直居中問題 int baseline = (screenHeight - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top + (int) (getResources().getDisplayMetrics().density * 45 + 0.5f); canvas.drawText(testStr, screenWidth / 2 - bounds.width() / 2, baseline, mPaint); } //繪製參加者資訊 private void drawPartText(Canvas canvas) { String testStr = "我是第4890位參與者"; Paint mPaint = new Paint(); mPaint.setStrokeWidth(2); mPaint.setTextSize(resizeTextSize(22)); mPaint.setColor(Color.RED); mPaint.setTextAlign(Paint.Align.LEFT); Rect bounds = new Rect(); mPaint.getTextBounds(testStr, 0, testStr.length(), bounds); Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt(); //處理字型垂直居中問題 計算文字到頂部的距離 int baseline = (screenHeight - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top + (int) (getResources().getDisplayMetrics().density * 190 + 0.5f); canvas.drawText(testStr, screenWidth / 2 - bounds.width() / 2, baseline, mPaint); }
- 繪製圓形頭像
private void drawAvatars(Canvas canvas) { Bitmap avatarsBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.avatars); canvas.drawBitmap(toRoundBitmap(avatarsBitmap), screenWidth / 2 - 50, screenHeight / 2 - 50 + (int) (getResources().getDisplayMetrics().density * 155 + 0.5f), null); } //繪製圓形頭像 private Bitmap toRoundBitmap(Bitmap bitmap) { bitmap = Bitmap.createScaledBitmap(bitmap, 100, 100, true); Bitmap bm = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bm); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); // 這裡需要先畫出一個圓 canvas.drawCircle(50, 50, 50, paint); // 圓畫好之後將畫筆重置一下 paint.reset(); // 設定影象合成模式,該模式為只在源影象和目標影象相交的地方繪製源影象 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, 0, 0, paint); return bm; }
- 字型適配
/* * 說明:該方法是適配不同解析度手機的字型大小 * 以720,1080螢幕為基準,這個size自己定義。 */ private int resizeTextSize(int size) { DisplayMetrics dm = getResources().getDisplayMetrics(); int mScreenWidth = dm.widthPixels; int mScreenHeight = dm.heightPixels; float ratioWidth = (float) mScreenWidth / 720; float ratioHeight = (float) mScreenHeight / 1080; float ratioMetrics = Math.min(ratioWidth, ratioHeight); return Math.round(size * ratioMetrics); }
3.總結
- 我們在開發過程中當有個新需求的時候,首先是對需求進行理解,找到解決問題的入口和方法
- canvas和bitmap之間的關係
- 文章只為自己養成良好的記錄問題習慣,大手勿噴