图像分析-RGBA模型

R:红色 G:绿色 B:蓝色 A:透明度

  • 色调/色相 : 物体传递的颜色
  • 饱和度:颜色的纯度
  • 亮度/明度:颜色的相对明暗程度

PS:可以用PS去试验一下对这个的理解会比较好。
Android中可以通过ColorMatrix类中的方法对色调/色相,饱和度以及亮度/明度进行调节,如下:

//色调
ColorMatrix hueMatrix = new ColorMatrix();
hueMatrix.setRotate(0,hue);//0为红色
hueMatrix.setRotate(1,hue);//1为绿色
hueMatrix.setRotate(2,hue);//2为蓝色
//饱和度
ColorMatrix saturationMatrix = new ColorMatrix();
saturationMatrix.setSaturation(saturation);
//亮度
ColorMatrix lumMatrix = new ColorMatrix();
lumMatrix.setScale(lum,lum,lum,1);

分装起来呢就是图像处理工具类:

package com.xjh.gin.image;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;

/**
 * Created by Gin on 2017/11/25.
 */

public class ImageHelper {
    public static Bitmap handleImageEffect(Bitmap bm, float hue, float saturation, float lum) {//bm图像,hue色相,saturation饱和度,lum亮度
        //传进来的bitmap是不能修改的
        Bitmap bmp = Bitmap.createBitmap(bm.getWidth(),bm.getHeight(), Bitmap.Config.ARGB_8888);//最后一个是bitmap的处理方式
        Canvas canvas = new Canvas(bmp);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿
        //色调
        ColorMatrix hueMatrix = new ColorMatrix();
        hueMatrix.setRotate(0,hue);//0为红色
        hueMatrix.setRotate(1,hue);//1为绿色
        hueMatrix.setRotate(2,hue);//2为蓝色
        //饱和度
        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(bm,0,0,paint);
        return bmp;
    }
}

来个例子:
新建一个primary_color.xml的布局,里面有一个ImageButton来到本地相册获取图片,然后有3个SeekBar来调节色调,饱和度以及亮度(代码如下)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageButton
        android:id="@+id/id_image"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_centerHorizontal="true"
        android:src="@mipmap/ic_launcher"
        android:layout_marginTop="15dp"
        android:layout_marginBottom="10dp"
        />

    <TextView
        android:id="@+id/id_hue"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:text="色调"
        android:layout_below="@+id/id_image"/>

    <android.support.v7.widget.AppCompatSeekBar
        android:id="@+id/seekbarHue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/id_hue"/>

    <TextView
        android:id="@+id/id_saturation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="饱和度"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:layout_below="@+id/seekbarHue"/>

    <android.support.v7.widget.AppCompatSeekBar
        android:id="@+id/seekbarSaturation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/id_saturation"/>

    <TextView
        android:id="@+id/id_lum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:text="亮度"
        android:layout_below="@+id/seekbarSaturation"/>

    <android.support.v7.widget.AppCompatSeekBar
        android:id="@+id/seekbarLum"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/id_lum"/>

</RelativeLayout>

然后我们来编写活动的代码,我们之前编写了图像处理工具类ImageHelper,然后我们用onProgressChanged监听SeekBar的变化,通过转化为数值,通过ImageHelper中的handleImageEffect方法改变图像的色调,饱和度以及亮度(代码如下)

package com.xjh.gin.image;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ImageButton;
import android.widget.SeekBar;

/**
 * Created by Gin on 2017/11/25.
 */

public class PrimaryColor extends BaseActivity implements SeekBar.OnSeekBarChangeListener,View.OnClickListener {

    private static final int PICK_CODE = 0X110;
    private ImageButton mImage;
    private SeekBar mSeekbarHue, mSeekbarSaturation, mSeekbarLum;
    private static int MAX_VALUE = 255;
    private static int MID_VALUE = 127;
    private float mHue, mSaturation, mLum;
    private String mCurreatPhotoStr;
    private Bitmap bitmap;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.primary_color);
        isPermissionAllGranted(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
        initView();
        initEvent();
    }

    private void initEvent() {
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
        mImage.setOnClickListener(this);
        mSeekbarHue.setOnSeekBarChangeListener(this);
        mSeekbarSaturation.setOnSeekBarChangeListener(this);
        mSeekbarLum.setOnSeekBarChangeListener(this);
        mSeekbarHue.setMax(MAX_VALUE);
        mSeekbarSaturation.setMax(MAX_VALUE);
        mSeekbarLum.setMax(MAX_VALUE);
        mSeekbarHue.setProgress(MID_VALUE);
        mSeekbarSaturation.setProgress(MID_VALUE);
        mSeekbarLum.setProgress(MID_VALUE);
        mImage.setImageBitmap(bitmap);
    }

    private void initView() {
        mImage = (ImageButton) findViewById(R.id.id_image);
        mSeekbarHue = (SeekBar) findViewById(R.id.seekbarHue);
        mSeekbarSaturation = (SeekBar) findViewById(R.id.seekbarSaturation);
        mSeekbarLum = (SeekBar) findViewById(R.id.seekbarLum);
    }

    @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.seekbarLum:
                mLum = progress * 1.0f / MID_VALUE;
                break;
        }
        mImage.setImageBitmap(ImageHelper.handleImageEffect(bitmap, mHue, mSaturation, mLum));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.id_image:
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType("image/*");
                startActivityForResult(intent, PICK_CODE);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PICK_CODE) {
            if (data != null) {
                Uri uri = data.getData();
                Cursor cursor = getContentResolver().query(uri, null, null, null, null);
                cursor.moveToFirst();
                int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                mCurreatPhotoStr = cursor.getString(idx);
                cursor.close();
                resizePhoto();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    private void resizePhoto() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//true为不加载图片,只有宽高这类的数据
        BitmapFactory.decodeFile(mCurreatPhotoStr, options);

        double ratio = Math.max(options.outWidth * 1.0d / 1024f, options.outHeight * 1.0d / 1024f);//求出压缩比例
        options.inSampleSize = (int) Math.ceil(ratio);//把压缩比例传入options中
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(mCurreatPhotoStr, options);
        mImage.setImageBitmap(bitmap);//压缩图片,mPhoto是压缩过后的Bitmap
    }
}

这里写图片描述

项目GitHub地址:传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值