圖片處理之貼紙(水印)

一直想對之前做過的一款圖片社交軟件cos醬(類似in nice)的代碼進行梳理别厘,但是由于時間的關(guān)系拖到今天才開始這個工作怎棱。
在項目中哩俭,主要對照片裁剪、旋轉(zhuǎn)拳恋、翻轉(zhuǎn)(在之前的文章有提到過)凡资、貼紙、濾鏡谬运、文字隙赁、邊框、標簽等功能梆暖。

如何添加貼紙

  1. 自定義WaterMarkView;
  2. 移動伞访、縮放貼紙(用戶的操作行為);
  3. 合成圖片轰驳。

自定義WaterMarkView

具體如下圖

示例

有圖片中我們可以看到厚掷,貼紙由3部分組成(主體內(nèi)容、刪除按鈕级解、縮放按鈕)冒黑。
所以在ondraw中
canvas.drawBitmap(mBitmap, matrix, paint); mPath.reset(); mPath.moveTo(mLTPoint.x,mLTPoint.y); mPath.lineTo(mRTPoint.x, mRTPoint.y); mPath.lineTo(mRBPoint.x, mRBPoint.y); mPath.lineTo(mLBPoint.x, mLBPoint.y); mPath.lineTo(mLTPoint.x, mLTPoint.y); mPath.lineTo(mRTPoint.x, mRTPoint.y); canvas.drawPath(mPath, mPaint);//畫旋轉(zhuǎn), 縮放圖標controlDrawable.setBounds(mControlPoint.x - mDrawableWidth / 2, mControlPoint.y - mDrawableHeight / 2, mControlPoint.x + mDrawableWidth / 2, mControlPoint.y + mDrawableHeight/2); controlDrawable.draw(canvas); removeDrawable.setBounds(mremovePoint.x - mRemoveDrawableWidth / 2, mremovePoint.y - mRemoveDrawableHeight / 2, mremovePoint.x + mRemoveDrawableWidth / 2, mremovePoint.y + mRemoveDrawableHeight / 2); removeDrawable.draw(canvas);

然后結(jié)合GestureDetector和onTouchEvent進行縮放、移動蠕趁、刪除操作薛闪。具體代碼如下:
switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: if (!isEditable) { //取消其余貼紙的編輯狀態(tài),只有一個處于編輯狀態(tài) Bundle bundle = new Bundle(); bundle.putSerializable("selectWaterMarkView", this); EventBus.getEventBus().post(new BasePostEvent(CosCameraConstants.WATER_MARK_EDITSTATE_CANCLE, bundle)); //設(shè)置本身被選中 setEditState(true); } mPreMovePointF.set(event.getX() + mViewPaddingLeft, event.getY() + mViewPaddingTop); mStatus = JudgeStatus(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: mStatus = STATUS_INIT; WaterMarkClicked(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: mCurMovePointF.set(event.getX() + mViewPaddingLeft, event.getY() + mViewPaddingTop); if (mStatus == STATUS_ROTATE_ZOOM) { float scale = 1f; int halfBitmapWidth = mBitmap.getWidth() / 2; int halfBitmapHeight = mBitmap.getHeight() / 2; //圖片某個點到圖片中心的距離 float bitmapToCenterDistance = FloatMath.sqrt(halfBitmapWidth * halfBitmapWidth + halfBitmapHeight * halfBitmapHeight); //移動的點到圖片中心的距離 float moveToCenterDistance = distance4PointF(mCenterPoint, mCurMovePointF); //計算縮放比例 scale = moveToCenterDistance / bitmapToCenterDistance; //縮放比例的界限判斷 if (scale <= MIN_SCALE) { scale = MIN_SCALE; } else if (scale >= MAX_SCALE) { scale = MAX_SCALE; } // 角度 double a = distance4PointF(mCenterPoint, mPreMovePointF); double b = distance4PointF(mPreMovePointF, mCurMovePointF); double c = distance4PointF(mCenterPoint, mCurMovePointF); double cosb = (a * a + c * c - b * b) / (2 * a * c); if (cosb >= 1) { cosb = 1f; } double radian = Math.acos(cosb); float newDegree = (float) radianToDegree(radian); //center -> proMove的向量俺陋, 我們使用PointF來實現(xiàn) PointF centerToProMove = new PointF((mPreMovePointF.x - mCenterPoint.x), (mPreMovePointF.y - mCenterPoint.y)); //center -> curMove 的向量 PointF centerToCurMove = new PointF((mCurMovePointF.x - mCenterPoint.x), (mCurMovePointF.y - mCenterPoint.y)); //向量叉乘結(jié)果, 如果結(jié)果為負數(shù)豁延, 表示為逆時針, 結(jié)果為正數(shù)表示順時針 float result = centerToProMove.x * centerToCurMove.y - centerToProMove.y * centerToCurMove.x; if (result < 0) { newDegree = -newDegree; } mDegree = mDegree + newDegree; mScale = scale; transformDraw(); } else if (mStatus == STATUS_REMOVE) { this.mOnRemoveWaterListener.onRemoveClick(this); } else if (mStatus == STATUS_DRAG) { // 修改中心點 mCenterPoint.x += mCurMovePointF.x - mPreMovePointF.x; mCenterPoint.y += mCurMovePointF.y - mPreMovePointF.y; adjustLayout(); } mPreMovePointF.set(mCurMovePointF); break; }
重要方法transformDraw()介紹
/** * 設(shè)置Matrix, 強制刷新 */ public void transformDraw(){ int bitmapWidth = (int)(mBitmap.getWidth() * mScale); int bitmapHeight = (int)(mBitmap.getHeight()* mScale); computeRect(-framePadding, -framePadding, bitmapWidth + framePadding, bitmapHeight + framePadding, mDegree); //設(shè)置縮放比例 matrix.setScale(mScale, mScale); //繞著圖片中心進行旋轉(zhuǎn) matrix.postRotate(mDegree % 360, bitmapWidth/2, bitmapHeight/2); //設(shè)置畫該圖片的起始點 matrix.postTranslate(offsetX + mDrawableWidth/2, offsetY + mDrawableHeight/2); invalidate(); }
重要方法transformDraw()介紹
/** * 調(diào)整View的大小腊状,位置 */ public void adjustLayout(){ int actualWidth = mViewWidth + mDrawableWidth; int actualHeight = mViewHeight + mDrawableHeight; int newPaddingLeft = (int) (mCenterPoint.x - actualWidth /2); int newPaddingTop = (int) (mCenterPoint.y - actualHeight/2); if(mViewPaddingLeft != newPaddingLeft || mViewPaddingTop != newPaddingTop){ mViewPaddingLeft = newPaddingLeft; mViewPaddingTop = newPaddingTop; layout(newPaddingLeft, newPaddingTop, newPaddingLeft + actualWidth, newPaddingTop + actualHeight); } }

合成圖片

很笨挫的辦法诱咏,通過view生成圖片:
Canvas canvas = new Canvas(new_bitmap); photo_area_rl.draw(canvas);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市缴挖,隨后出現(xiàn)的幾起案子袋狞,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苟鸯,死亡現(xiàn)場離奇詭異同蜻,居然都是意外死亡,警方通過查閱死者的電腦和手機早处,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門湾蔓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人砌梆,你說我怎么就攤上這事默责。” “怎么了咸包?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵桃序,是天一觀的道長。 經(jīng)常有香客問我烂瘫,道長媒熊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任忱反,我火速辦了婚禮泛释,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘温算。我一直安慰自己,他們只是感情好间影,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布注竿。 她就那樣靜靜地躺著,像睡著了一般魂贬。 火紅的嫁衣襯著肌膚如雪巩割。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天付燥,我揣著相機與錄音宣谈,去河邊找鬼。 笑死键科,一個胖子當著我的面吹牛闻丑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勋颖,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嗦嗡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了饭玲?” 一聲冷哼從身側(cè)響起侥祭,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后矮冬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谈宛,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年胎署,在試婚紗的時候發(fā)現(xiàn)自己被綠了入挣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡硝拧,死狀恐怖径筏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情障陶,我是刑警寧澤滋恬,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站抱究,受9級特大地震影響恢氯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鼓寺,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一勋拟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妈候,春花似錦敢靡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至幔虏,卻和暖如春纺念,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背想括。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工陷谱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瑟蜈。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓烟逊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親踪栋。 傳聞我的和親對象是個殘疾皇子焙格,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容