Android 图像处理2

 图片绘制原理:     

 1.  绘制背景图    绘制图层  被修改的
 2. 修改绘制图层
 3. 绘制修改图层

1. 案例1:   微信画板

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/iv"
        android:orientation="horizontal" >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="clickBrush"
            android:text="刷子" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="clickRed"
            android:text="红色" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="clickGreen"
            android:text="绿色" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="save"
            android:text="保存" />
    </LinearLayout>

</RelativeLayout>

 java 代码实现:

package mk.denganzhi.com.heimaimage;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;

public class WeiXingPaintActivity extends AppCompatActivity {

    private ImageView iv;
    private Canvas canvas;
    private Paint paint;
    private Bitmap srcBitmap;
    private Bitmap copyBitmap;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wei_xing_paint);

        iv = (ImageView) findViewById(R.id.iv);
        // 设置一个灰白色的背景 ,在这个背景资源上作画。
        srcBitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.background);
        // 创建原图的拷贝
        //  Bitmap.createBitmap(iv.getWidth(),iv.height(),Bitmap.Config.ARG_8888)
        // //  1.  绘制背景图(这里是背景图)    绘制图层(这里是图层)  被修改的
        copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),
                srcBitmap.getHeight(), srcBitmap.getConfig());
        canvas = new Canvas(copyBitmap);
        paint = new Paint();
        paint.setColor(Color.BLACK);

        //  1.  绘制背景图(这里是背景图)    绘制图层  被修改的
        canvas.drawBitmap(srcBitmap, new Matrix(), paint);

        // canvas.drawLine(10, 10, 80, 80, paint);

        iv.setOnTouchListener(new View.OnTouchListener() {
            int startX;
            int startY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // 获取到触摸事件的类型。
                int action = event.getAction();
                // 按下,移动,离开
                switch (action) {
                    case MotionEvent.ACTION_DOWN:// 按下
                        // 记录下手指第一次按下的坐标
                        startX = (int) event.getX();
                        startY = (int) event.getY();
                        System.out.println("按下:" + startX + "," + startY);
                        break;
                    case MotionEvent.ACTION_MOVE:// 移动
                        // 得到移动后的新的坐标
                        // 2. 修改绘制图层  修copyBitmap 图层上 继续绘制
                        int newX = (int) event.getX();
                        int newY = (int) event.getY();
                        canvas.drawLine(startX, startY, newX, newY, paint);
                        System.out.println("移动画线:" + startX + "," + startY + "~"
                                + newX + "," + newY);
                        // 获取新的起点坐标
                        startX = (int) event.getX();
                        startY = (int) event.getY();
                       //  3. 绘制修改图层
                        iv.setImageBitmap(copyBitmap);
                        // srcBitmap就是背景
                        // copyBitmap就是图层
                        break;
                    case MotionEvent.ACTION_UP:// 离开
                        break;
                }
                // True if the listener has consumed the event, false otherwise
                // true 代表监听器把事件处理完毕了,false代表没处理完毕
                return true;
            }
        });
        // 设置拷贝后的图片
        iv.setImageBitmap(copyBitmap);
    }

    public void clickBrush(View view) {
        // 设置画笔的宽度
        paint.setStrokeWidth(10);
    }

    public void clickRed(View view) {
        paint.setColor(Color.RED);
    }

    public void clickGreen(View view) {
        paint.setColor(Color.GREEN);
    }

    public void save(View view){
        try {
            File file = new File(Environment.getExternalStorageDirectory(),"haha.png");
            FileOutputStream stream = new FileOutputStream(file);
            copyBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            stream.close();
            Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
            //欺骗图库应用。模拟一个sd卡挂载的广播消息。
//            Intent intent = new Intent();
//            intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
//            intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
//            sendBroadcast(intent);

            // 必须要杀死图库,重新扫描爱可以读取sdcard
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri uri = Uri.fromFile(file);
            intent.setData(uri);
            sendBroadcast(intent);



        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(this, "保存失败", 0).show();
        }
    }
}

 上图看效果:

2. 去掉衣服      抽奖挂码原理

实现原理: 在修改的的图层,不断设置透明区域,覆盖图层

xml布局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >



    <ImageView
        android:id="@+id/iv_after"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />

    <ImageView
        android:id="@+id/iv_pre"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />

</FrameLayout>

Java代码实现:

package mk.denganzhi.com.heimaimage;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupWindow;

public class RemoveGrilActivity extends AppCompatActivity {

    private ImageView iv_after;
    private ImageView iv_before;
    private Bitmap aleterBitmap;
    private Paint paint;
    private Canvas canvas;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_remove_gril);



        // 这把是背景图
        iv_after=(ImageView) findViewById(R.id.iv_after);
        // 这个是被修改图
        iv_before=(ImageView) findViewById(R.id.iv_pre);

        BitmapFactory.Options opts=new BitmapFactory.Options();
        opts.inSampleSize=1; //缩小一点
        // 这里是只读图片
        Bitmap after=BitmapFactory.decodeResource(getResources(), R.drawable.after19,opts);
        Bitmap before=BitmapFactory.decodeResource(getResources(), R.drawable.background1,opts);
        // 这里是可以写的图片,可以修改的,空白的Bitmap
        aleterBitmap=Bitmap.createBitmap(before.getWidth(), before.getHeight(), before.getConfig());
        canvas=new Canvas(aleterBitmap);
        paint=new Paint();

        paint.setStrokeWidth(5);
        paint.setColor(Color.BLACK);
        canvas.drawBitmap(before, new Matrix(), paint);
        // 这把是背景图
        iv_after.setImageBitmap(after);
        // 被修改图
        iv_before.setImageBitmap(aleterBitmap);


        iv_before.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int newX=(int) event.getX();
                        int newY=(int) event.getY();
                  Log.e("denganzhi1","newX:"+newX +"  newY:"+ newY);
                  Log.e("denganzhi1","weidth"+ aleterBitmap.getWidth()+ "height:"+aleterBitmap.getHeight());
                        for(int i=-20;i<20;i++){
                            for(int j=-20;j<20;j++){
                                // 这里 x、y的值不能小于0、大于图片的宽高
                                // 透明读取不断你覆盖被修改图片
                                // 实际上点一下是一个圆形实现
                            int newX1= (i+newX);
                            int newY1 =(j+newY);
                                Log.e("denganzhi","x:" +newX1 +" y: "+ newY1);

                                aleterBitmap.setPixel(newX1, newY1, Color.TRANSPARENT);
                           }
                        }
                        iv_before.setImageBitmap(aleterBitmap);
                        break;
                    case MotionEvent.ACTION_UP:

                        break;

                }
                return true;
            }
        });
    }

}

图片效果图:

3. 图片合成

图片合成模式:

demo 实现xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <ImageView
        android:id="@+id/iv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LinearLayout>

 Java 代码实现:

package mk.denganzhi.com.heimaimage;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

public class ImageComposeActivity extends AppCompatActivity {
    private ImageView iv1;
    private ImageView iv2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_compose);

        iv1=(ImageView) findViewById(R.id.iv1);
        iv2=(ImageView) findViewById(R.id.iv2);
        BitmapFactory.Options opts=new BitmapFactory.Options();
        opts.inSampleSize=2;
        Bitmap bitmap1=BitmapFactory.decodeResource(getResources(),R.drawable.background1,opts);

        Bitmap alertBitmap = Bitmap.createBitmap(bitmap1.getWidth(), bitmap1.getHeight(), bitmap1.getConfig());
        Canvas canvas=new Canvas(alertBitmap);
        Paint paint=new Paint();
        paint.setColor(Color.BLACK);

        // 设置图片合成的样式
        // api demos-graphics- xfermodes
        paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DARKEN));
        //android.graphics.PorterDuff.Mode.DARKEN:重叠的地方图片颜色变暗了,就是一个水印效果
        //android.graphics.PorterDuff.Mode.Lighten:重叠的地方图片颜色变亮了
        // 比如大家来找茬外挂,把图片合成,然后显示出来
        // 画了第一张图片
        canvas.drawBitmap(bitmap1,new Matrix() , paint);
        // 画第二张图片
        Bitmap bitmap2=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        canvas.drawBitmap(bitmap2, new Matrix(), paint);

        iv2.setImageBitmap(alertBitmap);
    }
}

效果图:

4 . 矩阵效果实现 

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ImageView
        android:id="@+id/iv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

 Java代码实现:

package mk.denganzhi.com.heimaimage;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

public class MaxtidActivity extends AppCompatActivity {
    private ImageView iv1;
    private ImageView iv2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maxtid);


        iv1=(ImageView) findViewById(R.id.iv1);
        iv2=(ImageView) findViewById(R.id.iv2);

        Bitmap bitmap= BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        iv1.setImageBitmap(bitmap);

        Bitmap alertbitmap=Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
        Canvas canvas=new Canvas(alertbitmap);
        Paint paint=new Paint();
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);

        Matrix matrix=new Matrix();
//        matrix.setValues(new float[]{
//         0.5f,0,0,
//         0,1,0,
//         0,0,1
//        });
        // 1.距阵就是一个3*3数组
        // x= 0.5f*x + 0*y + 0*z  :  缩小0.5f倍
        // y= 0*x + 1*y + 0*z


        // google 考虑到大多数人已经不认识矩阵了
        //  matrix.setTranslate(10, 10);//  2.实现平移


        //3.  实现镜子效果
//        matrix.setScale(-1, 1);
//        matrix.postTranslate(bitmap.getWidth(),0);


        // 4. 倒影效果
        matrix.setScale(1, -1);
        matrix.postTranslate(0, bitmap.getHeight()); // 在原来的基础上倒影,然后移动到下面来
        // 把bitmap画上去,matir:对画上去的图片的操作  paint:画笔
        canvas.drawBitmap(bitmap,matrix , paint);

        iv2.setImageBitmap(alertbitmap);
    }
}

效果图:

     镜子效果                    倒影效果         

发布了112 篇原创文章 · 获赞 124 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/dreams_deng/article/details/105262449