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阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,471评论 6 30
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,104评论 5 13
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,815评论 25 707
  • $ gem sources --remove http://rubygems.org/$gemsources-ah...
    栋栋晓阅读 617评论 0 0
  • 《碰触》目录 六、谜 文/琉漓沙 葵回到家以后,躺在沙发上休息,她莫名的有些开心,不知怎的看着脚上的伤也并不...
    小小沙sally阅读 593评论 1 2