1. 程式人生 > >Canvas繪製Bitmap 友盟分享純圖片至微信好友

Canvas繪製Bitmap 友盟分享純圖片至微信好友

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物件。

  • canvasbitmap   
    網上有很多關於canvas的相關資料,canvas的其他內容就不在本篇文章中做說明,我們來看下canvasbitmap相關的知識點。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.總結

  •  我們在開發過程中當有個新需求的時候,首先是對需求進行理解,找到解決問題的入口和方法
  •  canvasbitmap之間的關係
  •  文章只為自己養成良好的記錄問題習慣,大手勿噴