Android仿海報工廠(完)

**0.0
東西到這里差不多到一段落了,整體效果還算比較成功的,好像就焦點釋放有些問題,當然還有很多瑕疵,這個完全可以根據自己需求去修改啦,我有空也會改改的。
**
先放圖:

pre.gif

filter.gif
switch.gif

上篇文章投稿“程序員”的時候被駁回了,原因是因為圖片不雅觀,所以這次就換了幾張圖。····

有點gay.jpg

下面講講主要更新的幾個地方:

(一)圖層的縮放?

圖層的縮放需要計算雙指最開始Down下的距離與Move過程中的距離的比值。
而所得出的scale比例都必須在上次scale的前提下進行,多指觸控的代碼我就不放出來了,大家可以去去看demo

圖片縮放的代碼如下,這里采用的是Matrix的縮放:

/**
     * 縮放圖層
     *
     * @param toSacle
     */
    protected void scaleLayer(float toSacle) {
        scale = scale * toSacle;
        if (scale >= max_scale)
            scale = max_scale;
        if (scale <= min_scale)
            scale = min_scale;
        Bitmap scaleLayer;
        if (filterLayer != null) {
            scaleLayer = BitmapUtils.scaleBitmap(filterLayer, scale);
        } else {
            scaleLayer = BitmapUtils.scaleBitmap(layer, scale);
        }
        BitmapUtils.destroyBitmap(drawLayer);
        drawLayer = scaleLayer;
        // 更新Layer的坐標
        setLayerX(x - (drawLayer.getWidth() - width) / 2);
        setLayerY(y - (drawLayer.getHeight() - height) / 2);
        width = drawLayer.getWidth();
        height = drawLayer.getHeight();
    }

(二)如何替換圖片順序?

先來分析下替換圖層順序的是一個什么樣情景:
1.手指選中一張圖層進行拖拽
2.拖拽過程中,坐標超出圖層范圍(這里并不只針對layer的范圍,還有一個平移的最大邊境)
3.拖拽至其他非選中layer范圍當中,在松手的同時,切換相對應的圖層。

這里感覺困難的地方主要還是在情景狀態的判斷,與ui變化,真要文字描述起來還挺煩人的,所以小伙伴們還是去看代碼吧,這里就不寫啦···

(三)如何設置圖片濾鏡?

濾鏡使用的是之前在Matrix(三)自己封裝的ColorFilter類。
在繪制的時候新增了一個的圖片對象,當判斷濾鏡圖片不為空的時候,所進行的圖片縮放使用不在是原圖,而是濾鏡圖片,代碼如下:

  /**
     * 設置濾鏡圖片
     *
     * @param filterLayer
     */
    public void setFilterLayer(Bitmap filterLayer) {
        this.filterLayer = filterLayer;
        //因為當前繪制的圖片使用的是原圖(或者濾鏡圖)縮放過后的圖,
        //所以當有濾鏡圖存在的同時需要將濾鏡圖進行縮放
        scaleLayer(1);
    }

    /**
     * 去除濾鏡圖
![Upload filter.gif failed. Please try again.]
     */
    public void clearFilter() {
        BitmapUtils.destroyBitmap(filterLayer);//方法里有致空操作
        filterLayer = null;
        scaleLayer(1);
    }

這個挺簡單的,如果當你們的濾鏡比較耗時時,處理完成之后將圖片設置回來即可,當然我還沒有做圖層內部的刷新,所以在設置完圖片濾鏡之后需要刷新modelview。

(四)如何在圖層上面進行彈窗?

我將重新封裝了一層PosterView繼承RelativeLayout,將modelview和菜單的view都添加在里面,主要代碼:

  private void viewInit() {
        modelView = new ModelView(getContext());
        modelParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        addView(modelView, modelParams);
    }

    /**
     * 濾鏡菜單初始化,并設置寬高
     *
     * @param menu
     * @param menuWidth
     */
    public void addMenuInit(View menu, int menuWidth, int menuHeight) {
        this.menu = menu;
        menuParams = new LayoutParams(menuWidth, menuHeight);
        addView(menu, menuParams);
        menu.setVisibility(GONE);
    }

    public void dissMenu() {
        if (null != menu)
            menu.setVisibility(GONE);
    }

    public void showMenu(Layer layer) {
        Layer.MenuPoint menuPoint = layer.getFrontMenuPoint(getHeight(), menuParams.height);
        PointF pointf = menuPoint.point;
        if (pointf.x + menuParams.width >= width) {
            pointf.x = width - menuParams.width;
        }
        if (menuPoint.direction == 1) {
            pointf.y = pointf.y - menuParams.height;
        }
        menuParams.setMargins((int) pointf.x, (int) pointf.y, 0, 0);
        menu.setLayoutParams(menuParams);
        if (null != menu)
            menu.setVisibility(VISIBLE);

    }

上面代碼中的 Layer.MenuPoint 乃是我在layer中計算出合適的菜單彈出的位置

  /**
     * 計算出菜單彈出的最優點
     *
     * @return
     */
    public MenuPoint getFrontMenuPoint(int height, int menuHeight) {
        PointF point = new PointF();
        MenuPoint menuPoint = null;
        if (height - MaxMenuPadding < layerRectF.bottom + menuHeight) {
            point.set(layerRectF.left, layerRectF.top);
            menuPoint = new MenuPoint(1, point);
        } else {
            point.set(layerRectF.left, layerRectF.bottom);
            menuPoint = new MenuPoint(0, point);
        }
        return menuPoint;
    }

    /**
     * 定義菜單坐標對象,
     * direction對應方向,0代表上,1代表下
     */
    public static class MenuPoint {
        int direction;
        PointF point;

        public MenuPoint(int direction, PointF point) {
            this.direction = direction;
            this.point = point;
        }
    }

(五)如何保存結果?

要想獲取結果Bitmap的寫法有很多,我這里生成了一張Bitmap,再獲取它的Canvas對象重新進行繪制。如下:

    public Bitmap getResult() {
        model.releaseAllFocus();//去除所有焦點,并刷新視圖
        this.invalidate();
        result = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        this.draw(canvas);
        return result;
    }

你也可以直接在FirstDraw的時候生成一張等高寬的圖片,使用圖片的canva進行繪圖,再繪制bitmap。
你更可以直接使用view截圖的方式進行獲取,但是需要注意的就是,在生成圖片之前必須釋放所有焦點,并刷新組件,不然 結果中會繪制邊框或者其他的東西。

項目地址

最新修改:解決旋轉180度平移反向的問題。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容

  • 在iOS中隨處都可以看到絢麗的動畫效果,實現這些動畫的過程并不復雜,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,545評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現這些動畫的過程并不復雜,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,133評論 5 13
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,686評論 25 708
  • $ gem sources --remove http://rubygems.org/$gemsources-ah...
    棟棟曉閱讀 620評論 0 0
  • 《碰觸》目錄 六、謎 文/琉漓沙 葵回到家以后,躺在沙發上休息,她莫名的有些開心,不知怎的看著腳上的傷也并不...
    小小沙sally閱讀 617評論 1 2