android图像处理
2016-08-10 13:45:24 qq_34304003 阅读数 97

一.图像处理事例

(1)实验目的

                    通过三个seekbar调节相片的色相、饱和度、亮度。

(2)步骤。
1.复制bitmap获取canvas设置抗锯齿画笔 因为是无法直接在原图上对图片进行修改的。

         Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmp);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    2.分别设置 色相、饱和度、亮度。
 ColorMatrix hueMatrix = new ColorMatrix();//设置色相 
        hueMatrix.setRotate(0, hue);
        hueMatrix.setRotate(1, hue);
        hueMatrix.setRotate(2, hue);
        // 0 1 2 分别代表红色绿色蓝色
ColorMatrix saturationMatrix = new ColorMatrix();
        saturationMatrix.setSaturation(saturation);
ColorMatrix lumMatrix = new ColorMatrix();
             lumMatrix.setScale(lum, lum, lum, 1);
            //设置亮度
    3.通过ColorMatrix对象的postContat方法封装
             ColorMatrix imageMatrix = new ColorMatrix();
             imageMatrix.postConcat(hueMatrix);
             imageMatrix.postConcat(saturationMatrix);
             imageMatrix.postConcat(lumMatrix);
paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
canvas.drawBitmap(bm, 0, 0, paint);
return bmp;
//绘制原有的bitmap
            4.对seekbar设置监听和点击事件
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        switch (seekBar.getId()) {
            case R.id.seekbarHue:
                mHue = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180;
                break;
            case R.id.seekbarSaturation:
                mStauration = progress * 1.0F / MID_VALUE;
                break;
            case R.id.seekbatLum:
                mLum = progress * 1.0F / MID_VALUE;
                break;
        }
        mImageView.setImageBitmap(ImageHelper.handleImageEffect(bitmap, mHue, mStauration, mLum));
    }
2017-03-21 16:20:38 liuweihhhh 阅读数 905

  本文是我在看过eclipse_xu大神的课程之后做的一些笔记,希望可以很好的掌握Android图片处理的相关知识。

一、图像色彩变换

1、RGBA模型和色相、饱和度、亮度

  RGBA是在R(Red)G(Green)B(Blue)模式上增加了alpha通道,alpha通道是不透明度。

  色相/色调:物体传递的颜色

ColorMatrix hueMatrix = new ColorMatrix();
hueMatrix.setRotate(0, hue); //R
hueMatrix.setRotate(1, hue); //G
hueMatrix.setRotate(2, hue); //B


  饱和度:颜色的准度,从0(灰)到100%(饱和)来进行描述

ColorMatrix saturationMatrix = new ColorMatrix();
saturationMatrix.setSaturation(saturation);


  亮度:颜色的相对明暗程度

ColorMatrix lumMatrix = new ColorMatrix();
// 4*5的色彩矩阵,第0、6、12、18位分别对应以下各个数值,分别控制红、绿、蓝和透明度
lumMatrix.setScale(lum, lum, lum, 1);


  在图像处理中,我们可以通过上面几种Android API来调整图片对应的色相、饱和度和亮度。将其封装进一个方法中,方便以后调用。

/**
     * @param bitmap     图像,传进来的bitmap是默认不可修改的,所以要重新创建一个与原图相同大小的Bitmap
     * @param hue        色相
     * @param saturation 饱和度
     * @param lum        亮度
     * @return 返回一张修改后的图片
     */
    public static Bitmap handleImageEffect(Bitmap bitmap, float hue, float saturation, float lum) {
        Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);        
        Canvas canvas = new Canvas(bmp);  //拥有一张与我们传进来的Bitmap一样大小的画布,之后的操作都讲在画布上完成
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);  //抗锯齿

        //这里必须要使用三个ColorMatrix,用一个只会有一个调整生效
        ColorMatrix hueMatrix = new ColorMatrix();
        hueMatrix.setRotate(0, hue); //R
        hueMatrix.setRotate(1, hue); //G
        hueMatrix.setRotate(2, hue); //B


        ColorMatrix saturationMatrix = new ColorMatrix();
        saturationMatrix.setSaturation(saturation);

        ColorMatrix lumMatrix = new ColorMatrix();
        lumMatrix.setScale(lum, lum, lum, 1);

        ColorMatrix imageMatrix = new ColorMatrix();
        imageMatrix.postConcat(hueMatrix);
        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(lumMatrix);

        paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
        canvas.drawBitmap(bitmap, 0, 0, paint);

        return bmp;
    }

2、矩阵变化

  ColorMatrix,Matrix是矩阵的意思。上面我们所做的操作其实也是对颜色矩阵进行处理,使图片展现出各种的变化。

  下图中的初始化矩阵,当它与任何颜色矩阵分量相乘得到的仍然是之前的颜色矩阵分量(像素点),所以它才被当做初始化矩阵。
  
  
  

  如下图所示,如果将左下角的矩阵带入,我们会得到R+100,G+100,B和透明度A不变的一个像素点

  
  

  将第二个矩阵带入,会得到一个R,B,A不变,G*2的像素点

  
  

  
  

  做一个例子,展示矩阵对图片的影响


  
  

3、像素点分析


  通过上面两部分的分析,我们知道ColorMatrix实际上是通过一个特定的矩阵去改变每一个像素点,甚至我们可以为每一个像素点添加不同的修改方法。比如我们在各种图片处理App中经常见到的底片效果、黑白照片、浮雕效果。如下图

1、底片效果
    //底片效果
    public static Bitmap handleImageNegetive(Bitmap bm) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        int color;
        int R, G, B, A;

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        int[] oldPx = new int[width * height];
        int[] newPx = new int[width * height];
        bm.getPixels(oldPx, 0, width, 0, 0, width, height);

        for (int i = 0; i < width * height; i++) {
            color = oldPx[i];
            R = Color.red(color);
            G = Color.green(color);
            B = Color.blue(color);
            A = Color.alpha(color);

            //主要算法
            R = 255 - R;
            G = 255 - G;
            B = 255 - B;

            if (R > 255) {
                R = 255;
            } else if (R < 0) {
                R = 0;
            }
            if (G > 255) {
                G = 255;
            } else if (G < 0) {
                G = 0;
            }
            if (B > 255) {
                B = 255;
            } else if (B < 0) {
                B = 0;
            }

            //合成新的颜色
            newPx[i] = Color.argb(A, R, G, B);
        }

        bitmap.setPixels(newPx, 0, width, 0, 0, width, height);

        return bitmap;
    }
2、黑白老照片效果
    //黑白老照片效果
    public static Bitmap handleImageOldPhoto(Bitmap bm) {
        Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
        int width = bm.getWidth();
        int height = bm.getHeight();
        int color = 0;
        int r, g, b, a, r1, g1, b1;

        int[] oldPx = new int[width * height];
        int[] newPx = new int[width * height];
        bm.getPixels(oldPx, 0, width, 0, 0, width, height);

        for (int i = 0; i < width * height; i++) {
            color = oldPx[i];
            r = Color.red(color);
            g = Color.green(color);
            b = Color.blue(color);
            a = Color.alpha(color);

            //主要算法
            r1 = (int) (0.393 * r + 0.769 * g + 0.189 * b);
            g1 = (int) (0.349 * r + 0.686 * g + 0.168 * b);
            b1 = (int) (0.272 * r + 0.534 * g + 0.131 * b);

            if (r1 > 255) {
                r1 = 255;
            }
            if (g1 > 255) {
                g1 = 255;
            }
            if (b1 > 255) {
                b1 = 255;
            }

            newPx[i] = Color.argb(a, r1, g1, b1);
        }
        bmp.setPixels(newPx, 0, width, 0, 0, width, height);
        return bmp;
    }
3、浮雕效果
    //浮雕效果
    //B.r = C.r-B.r + 127
    //B.g = C.g-B.g + 127
    //B.b = C.b-B.b + 127
    public static Bitmap handleImageRelief(Bitmap bm) {
        Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
        int width = bm.getWidth();
        int height = bm.getHeight();
        int color = 0, colorBefore = 0;
        int r, g, b, a, r1, g1, b1;

        int[] oldPx = new int[width * height];
        int[] newPx = new int[width * height];
        bm.getPixels(oldPx, 0, width, 0, 0, width, height);

        for (int i = 1; i < width * height; i++) {
            colorBefore = oldPx[i - 1];
            r = Color.red(colorBefore);
            g = Color.green(colorBefore);
            b = Color.blue(colorBefore);
            a = Color.alpha(colorBefore);

            color = oldPx[i];
            r1 = Color.red(color);
            g1 = Color.green(color);
            b1 = Color.blue(color);

            r = (r - r1 + 127);
            g = (g - g1 + 127);
            b = (b - b1 + 127);
            if (r > 255) {
                r = 255;
            }
            if (g > 255) {
                g = 255;
            }
            if (b > 255) {
                b = 255;
            }
            newPx[i] = Color.argb(a, r, g, b);
        }
        bmp.setPixels(newPx, 0, width, 0, 0, width, height);
        return bmp;
    }

二、图像图形变换

1、图形变换原理

  跟之前所学习到的颜色矩阵相同,在图形变化的时候可以使用变换矩阵对图片进行操作,基本原理和颜色矩阵相同。
  
  

  平移变换

  

  旋转变换

  

  缩放变换

  

  错切变换

  

  根据以上各种变换,可以得出如下结论:

  
  
  根据图形变化的原理,做一个例子展示:
  
  
  

2、画笔风格

1、Xfermode

Src 原图, Dst 遮罩层,如图所示,我们可以根据我们的需要,将两者堆叠起来,获取我们想要的图形。

  

看一下酷炫的效果:

  
  

private void InitView() {
        setLayerType(LAYER_TYPE_SOFTWARE, null);  //关闭硬件加速
        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);
        mOut = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(mOut);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //Dst 遮罩层 也可以做一个圆形的遮罩层,形成圆形图片
        //矩形圆角
        //canvas.drawRoundRect(0, 0, mBitmap.getWidth(), mBitmap.getHeight(), 50, 50, mPaint);
        //圆形图片
        canvas.drawCircle(mBitmap.getWidth() / 2, mBitmap.getHeight() / 2, mBitmap.getHeight() / 2, mPaint);

        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        //Src
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        mPaint.setXfermode(null);
    }

2、Shader

bitmapShader
    @Override
    protected void onDraw(Canvas canvas) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);
        //三种方式 CLAMP 拉伸 REPEAT 重复 MIRROR 镜像
        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint.setShader(mBitmapShader);
        //圆角矩形
        canvas.drawRoundRect(0, 0, mBitmap.getWidth(), mBitmap.getHeight(), 50, 50, mPaint);
        //圆形
        //canvas.drawCircle(mBitmap.getWidth() / 2, mBitmap.getHeight() / 2, mBitmap.getHeight() / 2, mPaint);
    }

以上Xfermode和bitmapShader都可以实现一个常用的圆形图片或圆角矩形图片,代码中也有体现

3、渐变Shader和Xfermode配合做出倒影效果

    private void initView() {
        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);

     Matrix matrix = new Matrix();
     //Scale是控制缩放,(1,-1)会将图片进行翻转,X轴对称
     matrix.setScale(1, -1);

     mReflectBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //线性渐变
        mPaint.setShader(new LinearGradient(0, mBitmap.getHeight(), 0, mBitmap.getHeight() * 1.4F, 0xDD000000, 0x10000000, Shader.TileMode.CLAMP));
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        canvas.drawBitmap(mBitmap, 0, 0, null);
        canvas.drawBitmap(mReflectBitmap, 0, mBitmap.getHeight(), null);
        canvas.drawRect(0, mBitmap.getHeight(), mBitmap.getWidth(), mBitmap.getHeight() * 2, mPaint);
    }

  

drawBitmapMesh

Mesh就是就是网格的意思,drawBitmapMesh就是将Bitmap分割成为若干个网格,操作每个交点处的坐标值,而达到操作图片图形的效果

    //一个坐标的横坐标存到数组奇数,纵坐标存到数组偶数位  修改后坐标
    private float[] verts = new float[Count * 2];

    //横坐标不变化,纵坐标做一个Sin()曲线变化
    @Override
    protected void onDraw(Canvas canvas) {

        for (int i = 0; i < Height + 1; i++) {
            for (int j = 0; j < Width + 1; j++) {
                //横坐标不变化
                verts[(i * (Width + 1) + j) * 2 + 0] += 0;

                float offsetY = (float) Math.sin((float) j / Width * 2 * Math.PI + k * 2 * Math.PI);
                verts[(i * (Width + 1) + j) * 2 + 1] = origs[(i * (Width + 1) + j) * 2 + 1] + offsetY * 50;
            }
        }
        k += 0.01F;
        canvas.drawBitmapMesh(mBitmap, Width, Height, verts, 0, null, 0, null);
        invalidate();
    }

  
  
  
  
  
代码地址ImageDome

2018-03-19 16:21:02 qq_36665856 阅读数 62
public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE"};


    private Button mButton;
    private ImageView mImage;
    private String TAG = "MainActivity";
    private File mFile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//6.0以后权限申请
 verifyStoragePermissions(MainActivity.this);
        mImage = (ImageView) findViewById(R.id.image);
        mButton = findViewById(R.id.button);
//将图片存入sd卡里
 mFile = new File(Environment.getExternalStorageDirectory() + "/abc.jpg");
        Bitmap bitmap1 = BitmapFactory.decodeFile(mFile.getAbsolutePath());
        mImage.setImageBitmap(bitmap1);
        Log.d(TAG, "剪裁前:" + bitmap1.getByteCount());

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bitmap bitmap2 = BitMapUtil.ratio(mFile.getAbsolutePath(), mImage.getWidth(), mImage.getHeight());
                Log.d(TAG, "剪裁后:" + bitmap2.getByteCount());
                mImage.setImageBitmap(bitmap2);
            }
        });
    }

    public static void verifyStoragePermissions(Activity activity) {
        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(activity,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


<?xml version="1.0" encoding="utf-8"?>
<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="com.yl.mybitmaptest.MainActivity">

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_margin="20dp" />


    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dp"
        android:text="加载图片" />

</RelativeLayout>

public class BitMapUtil {
    public static Bitmap ratio(String filePath, int pixelW, int pixelH) {
        BitmapFactory.Options newOptions = new BitmapFactory.Options();
        newOptions.inJustDecodeBounds = true;
        newOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        //预加载
        BitmapFactory.decodeFile(filePath, newOptions);
        int originalH = newOptions.outHeight;
        int originalW = newOptions.outWidth;
        newOptions.inSampleSize = getSimpleSize(originalW, originalH, pixelW, pixelH);
        newOptions.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, newOptions);
    }

    private static int getSimpleSize(int originalW, int originalH, int pixelW, int pixelH) {
        int simpleSize = 1;
        if (originalW > originalH && originalW > pixelW) {
            simpleSize = originalW / pixelW;
        } else if (originalW < originalH && originalH > pixelH) {
            simpleSize = originalH / pixelH;
        }
        if (simpleSize <= 0) {
            simpleSize = 1;
        }
        return simpleSize;
    }
}



2015-04-02 23:25:00 zhoumushui 阅读数 1113

在imooc上看了eclipse_xu的课程《Android图像处理》,照葫芦画瓢写了一个Demo:
看一下效果图:
这里写图片描述

核心代码:

package com.zms.imageprocess;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;

/**
 * Created by Administrator on 2015/4/1.
 */
public class PrimaryColorActivity extends Activity {
    private ImageView imageView;
    private SeekBar seekBarHue, seekBarSaturation, seekBarLuminance;
    private float mHue = 0.0f;
    private float mSaturation = 1.0f;
    private float mLuminance = 1.0f;
    private static int MAX_VALUE = 255;
    private static int MID_VALUE = 127;

    private Bitmap bitmap;
    private Button btnReset;
    private int imageFlag = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.primary_color);
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.map);
        imageView = (ImageView) findViewById(R.id.imageView);
        imageView.setImageBitmap(bitmap);
        imageView.setOnClickListener(new MyOnClickListener());

        btnReset = (Button) findViewById(R.id.btnReset);
        btnReset.setOnClickListener(new MyOnClickListener());

        seekBarHue = (SeekBar) findViewById(R.id.seekBarHue);
        seekBarHue.setMax(MAX_VALUE);
        seekBarHue.setProgress(MID_VALUE);
        seekBarHue.setOnSeekBarChangeListener(new MyOnSeekBarChangeListener());

        seekBarSaturation = (SeekBar) findViewById(R.id.seekBarSaturation);
        seekBarSaturation.setMax(MAX_VALUE);
        seekBarSaturation.setProgress(MID_VALUE);
        seekBarSaturation.setOnSeekBarChangeListener(new MyOnSeekBarChangeListener());

        seekBarLuminance = (SeekBar) findViewById(R.id.seekBarLuminance);
        seekBarLuminance.setMax(MAX_VALUE);
        seekBarLuminance.setProgress(MID_VALUE);
        seekBarLuminance.setOnSeekBarChangeListener(new MyOnSeekBarChangeListener());

    }

    class MyOnSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            switch (seekBar.getId()) {
                case R.id.seekBarHue:
                    mHue = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180;
                    break;
                case R.id.seekBarSaturation:
                    mSaturation = progress * 1.0F / MID_VALUE;
                    break;
                case R.id.seekBarLuminance:
                    mLuminance = progress * 1.0F / MID_VALUE;
                    break;
            }
            imageView.setImageBitmap(ImageHelper.ImageEffect(bitmap, mHue, mSaturation, mLuminance));
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    }

    class MyOnClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.imageView:
                    if (imageFlag == 0) {
                        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.aya);
                        imageView.setImageBitmap(bitmap);
                        imageFlag = 1;
                    } else if (imageFlag == 1) {
                        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.map);
                        imageView.setImageBitmap(bitmap);
                        imageFlag = 0;
                    }
                    break;
                case R.id.btnReset:
                    imageView.setImageBitmap(ImageHelper.ImageEffect(bitmap, 0.0f, 1.0f, 1.0f));
                    seekBarHue.setProgress(MID_VALUE);
                    seekBarSaturation.setProgress(MID_VALUE);
                    seekBarLuminance.setProgress(MID_VALUE);
                    break;
            }
        }
    }
}

Duang Duang~
学习一下原理:

Matrix:
其中e,j,o,t为偏移量

aR+bG+cB+dA+e
fR+gG+hB+iA+j
kR+lG+mB+nA+o
pR+qG+rB+sA+t

=

R1
G1
B1
A1

在onCreate函数中用post来获取组件的宽高:

        mGroup.post(new Runnable() {
            @Override
            public void run() {
                mEtWidth = mGroup.getWidth() / 5;
                mEtHeight = mGroup.getHeight() / 4;
                addEts();
                initMatrix();
            }
        });

这里写图片描述

最后一弹,共实现负片,怀旧,浮雕,灰度,圆角,油画和左右对称7种特效:
实现的ImageHelper如下:

package com.zms.imageprocess;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;

import java.util.Random;

/**
 * Created by Administrator on 2015/4/1.
 */
public class ImageHelper {
    // hue-色相 saturation-饱和度 lum-亮度
    public static Bitmap ImageEffect(Bitmap bitmap, float hue, float saturation, float luminance) {

        Bitmap mBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mBitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        // Hue-色相/色调
        ColorMatrix hueMatrix = new ColorMatrix();
        hueMatrix.setRotate(0, hue); // RED
        hueMatrix.setRotate(1, hue); // GREEN
        hueMatrix.setRotate(2, hue); // BLUE

        // Saturation-饱和度
        ColorMatrix saturationMatrix = new ColorMatrix();
        saturationMatrix.setSaturation(saturation);

        // Luminance-亮度/明度
        ColorMatrix luminanceMatrix = new ColorMatrix();
        //  setScale(float rScale, float gScale, float bScale, float aScale)
        luminanceMatrix.setScale(luminance, luminance, luminance, 1);

        ColorMatrix imageMatrix = new ColorMatrix();
        imageMatrix.postConcat(hueMatrix);
        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(luminanceMatrix);

        paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
        // drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint)
        canvas.drawBitmap(bitmap, 0, 0, paint);

        return mBitmap;
    }


    public static Bitmap handleImage(Bitmap bm, int effect) {
        Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),
                Bitmap.Config.ARGB_8888);
        int width = bm.getWidth();
        int height = bm.getHeight();
        int color = 0;
        int r, g, b, a, r1, g1, b1;
        int[] oldPx = new int[width * height];
        int[] newPx = new int[width * height];

        bm.getPixels(oldPx, 0, width, 0, 0, width, height);
        switch (effect) {

            case 0: // 负片效果
                for (int i = 0; i < width * height; i++) {
                    color = oldPx[i];
                    r = Color.red(color);
                    g = Color.green(color);
                    b = Color.blue(color);
                    a = Color.alpha(color);

                    r = 255 - r;
                    g = 255 - g;
                    b = 255 - b;

                    if (r > 255) {
                        r = 255;
                    } else if (r < 0) {
                        r = 0;
                    }
                    if (g > 255) {
                        g = 255;
                    } else if (g < 0) {
                        g = 0;
                    }
                    if (b > 255) {
                        b = 255;
                    } else if (b < 0) {
                        b = 0;
                    }
                    newPx[i] = Color.argb(a, r, g, b);
                }
                bitmap.setPixels(newPx, 0, width, 0, 0, width, height);
                break;
            case 1: // 怀旧效果
                for (int i = 0; i < width * height; i++) {
                    color = oldPx[i];
                    a = Color.alpha(color);
                    r = Color.red(color);
                    g = Color.green(color);
                    b = Color.blue(color);

                    r1 = (int) (0.393 * r + 0.769 * g + 0.189 * b);
                    g1 = (int) (0.349 * r + 0.686 * g + 0.168 * b);
                    b1 = (int) (0.272 * r + 0.534 * g + 0.131 * b);

                    if (r1 > 255) {
                        r1 = 255;
                    }
                    if (g1 > 255) {
                        g1 = 255;
                    }
                    if (b1 > 255) {
                        b1 = 255;
                    }
                    newPx[i] = Color.argb(a, r1, g1, b1);
                }
                bitmap.setPixels(newPx, 0, width, 0, 0, width, height);
                break;
            case 2: // 浮雕效果
                int colorBefore = 0;
                for (int i = 1; i < width * height; i++) {
                    colorBefore = oldPx[i - 1];
                    a = Color.alpha(colorBefore);
                    r = Color.red(colorBefore);
                    g = Color.green(colorBefore);
                    b = Color.blue(colorBefore);

                    color = oldPx[i];
                    r1 = Color.red(color);
                    g1 = Color.green(color);
                    b1 = Color.blue(color);

                    r = (r - r1 + 127);
                    g = (g - g1 + 127);
                    b = (b - b1 + 127);
                    if (r > 255) {
                        r = 255;
                    }
                    if (g > 255) {
                        g = 255;
                    }
                    if (b > 255) {
                        b = 255;
                    }
                    newPx[i] = Color.argb(a, r, g, b);
                }
                bitmap.setPixels(newPx, 0, width, 0, 0, width, height);
                break;
            case 3: // 灰度
                int alpha = 0xFF << 24;
                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        int grey = oldPx[width * i + j];
                        int red = ((grey & 0x00FF0000) >> 16);
                        int green = ((grey & 0x0000FF00) >> 8);
                        int blue = (grey & 0x000000FF);
                        grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
                        grey = alpha | (grey << 16) | (grey << 8) | grey;
                        newPx[width * i + j] = grey;
                    }
                }
                bitmap.setPixels(newPx, 0, width, 0, 0, width, height);
                break;
            case 4: // 圆角
                int roundPx = 55;
                Canvas canvas = new Canvas(bitmap);

                int colorRound = 0xff424242;
                Paint paint = new Paint();
                Rect rect = new Rect(0, 0, bm.getWidth(), bm.getHeight());
                RectF rectF = new RectF(rect);

                paint.setAntiAlias(true);
                canvas.drawARGB(0, 0, 0, 0);
                paint.setColor(colorRound);
                canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

                paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                canvas.drawBitmap(bm, rect, rect, paint);
                break;
            case 5: // 油画
                int Radio = 0;
                Random rnd = new Random();
                int iModel = 10;
                int i = width - iModel;
                while (i > 1) {
                    int j = height - iModel;
                    while (j > 1) {
                        int iPos = rnd.nextInt(10) % iModel;
                        color = bm.getPixel(i + iPos, j + iPos);
                        bitmap.setPixel(i, j, color);
                        j = j - 1;
                    }
                    i = i - 1;
                }
                break;
            case 6: // 左右对称
                Canvas canvas2 = new Canvas(bitmap);
                canvas2.drawColor(Color.BLACK);
                canvas2.drawBitmap(bm, 0, 0, null);
                Matrix matrix = new Matrix();
                float[] values = {-1f, 0.0f, 0.0f, 0.0f, 1f, 0.0f, 0.0f, 0.0f, 1.0f};
                matrix.setValues(values);
                bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(),
                        matrix, true);
                canvas2.drawBitmap(bitmap, bm.getWidth(), 0, null);
                break;
        }
        return bitmap;
    }

}

图像虚化:

上图是原图,下图是虚幻化后效果,可以拖拽SeekBar进行不同程度的虚化,如下:
这里写图片描述

package com.zms.blureffect;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.widget.ImageView;
import android.widget.SeekBar;

import java.lang.reflect.Field;

public class Main extends Activity {
private int scaleWidth = 100;
private int scaleHeight = 100;
private int radius = 5;
private Drawable blurImage;
private String TAG = “BLUR”;

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

    SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar1);
    seekBar.setMax(24);
    seekBar.setOnSeekBarChangeListener(new SeekBarListener());

    Display display = this.getWindowManager().getDefaultDisplay();
    scaleWidth = display.getWidth();
    scaleHeight = (display.getHeight() - getStatusBarHeight()) / 2;
    blurImage = getResources().getDrawable(R.drawable.note); // 要模糊的图片
    BlurImage(blurImage, radius);
}

private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {
    // boolean fromUser 是用户操作进度条,还是代码中setProgress
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        System.out.println(progress);
        if (seekBar.getProgress() > 0) {
            BlurImage(blurImage, seekBar.getProgress());
        } else {
            // 当模糊半径为0时显示原图
            ImageView imgAfter = (ImageView) findViewById(R.id.imgAfter);
            Bitmap bitmapAfter = ((BitmapDrawable) blurImage).getBitmap();
            Bitmap bitmapAfterAdjust = Bitmap.createScaledBitmap(bitmapAfter, scaleWidth,
                    scaleHeight, true); // 调整大小
            imgAfter.setImageBitmap(bitmapAfterAdjust);
        }
    }

    // 当用户开始滑动进度条时
    public void onStartTrackingTouch(SeekBar seekBar) {
        System.out.println("Start-->" + seekBar.getProgress());
    }

    // 当用户结束滑动进度条时
    public void onStopTrackingTouch(SeekBar seekBar) {
        System.out.println("Stop-->" + seekBar.getProgress());
    }
}

public void BlurImage(Drawable blurImage, int radius) {
    // 模糊前:
    ImageView imgBefore = (ImageView) findViewById(R.id.imgBefore);
    // Bitmap bitmapBefore =
    // BitmapFactory.decodeResource(getResources(),R.drawable.note); // 方法一
    Bitmap bitmapBefore = ((BitmapDrawable) blurImage).getBitmap(); // 方法二:drawable转成bitmap
    Bitmap bitmapBeforeAdjust = Bitmap.createScaledBitmap(bitmapBefore,
            scaleWidth, scaleHeight, true);
    imgBefore.setImageBitmap(bitmapBeforeAdjust);
    // 模糊后:
    ImageView imgAfter = (ImageView) findViewById(R.id.imgAfter);
    Bitmap bitmapAfter = Blur.fastblur(this, bitmapBefore, radius); // 第三个参数是模糊半径:0<radius<25
    Bitmap bitmapAfterAdjust = Bitmap.createScaledBitmap(bitmapAfter,
            scaleWidth, scaleHeight, true); // 调整大小
    imgAfter.setImageBitmap(bitmapAfterAdjust);
}

/**
 * 获取状态栏的高度
 *
 * @return int
 */
private int getStatusBarHeight() {
    Class<?> c = null;
    Object obj = null;
    Field field = null;
    int x = 0;
    try {
        c = Class.forName("com.android.internal.R$dimen");
        obj = c.newInstance();
        field = c.getField("status_bar_height");
        x = Integer.parseInt(field.get(obj).toString());
        return getResources().getDimensionPixelSize(x);
    } catch (Exception e1) {
        Log.d(TAG, " !!! get status bar height failed");
        e1.printStackTrace();
        return 75;
    }
}

}
完整的代码我会同步到我的GitHub上。

图片的缩放和拖动

这里写图片描述
代码下载

转载请注明出处:周木水的CSDN博客

2015-11-06 10:21:11 f5647 阅读数 290

http://www.oschina.net/question/231733_44154

http://blog.csdn.net/sjf0115/article/details/7267063

http://blog.csdn.net/WYHuan1030/article/category/3113937

android和图像处理

阅读数 22

Android的图像处理

阅读数 21

Android 图像处理

阅读数 7

博文 来自: niohandsome
没有更多推荐了,返回首页