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之間的關係
- 文章只爲自己養成良好的記錄問題習慣,大手勿噴