Android 使用ColorMatrix改变图片颜色

2023-05-16

ColorMatrix的颜色矩阵介绍

  • 颜色矩阵M是一个5*4的矩阵,在Android中,颜色矩阵M是以一维数组m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式进行存储的。如下图1:

图1 颜色矩阵M
图1 颜色矩阵M

他通过RGBA四个通道来直接操作对应颜色,达到修改图像的效果。

  • 第一行决定红色 R
  • 第二行决定绿色 G
  • 第三行决定蓝色 B
  • 第四行决定了透明度 A
  • 第五列是颜色的偏移量

原图的RGBA的ColorMatrix颜色矩阵数组为:

[ 1, 0, 0, 0, 0,
  0, 1, 0, 0, 0,
  0, 0, 1, 0, 0,
  0, 0, 0, 1, 0]
  • 在一张图片中,图像的RGBA(红色、绿色、蓝色、透明度)值决定了该图片所呈现出来的颜色效果。而图像的RGBA值则存储在一个5*1的颜色分量矩阵C中,由颜色分量矩阵C可以控制图像的颜色效果。颜色分量矩阵C 如图2所示:
    颜色分量矩阵C
    图2 颜色分量矩阵C

  • 要想改变一张图片的颜色效果,只需要改变图像的颜色分量矩阵即可。通过颜色矩阵可以很方便的修改图像的颜色分量矩阵。假设修改后的图像颜色分量矩阵为C1,则有如图3所示的颜色分量矩阵计算公式:
    这里写图片描述
    图3 颜色分量矩阵计算公式

通常,改变颜色分量时可以通过修改第5列的颜色偏移量来实现,如图4所示的颜色矩阵M1,通过计算后可以得知该颜色矩阵的作用是使图像的红色分量和绿色分量均增加100,这样的效果就是图片泛黄(因为红色与绿色混合后得到黄色)。
颜色矩阵M1
图4 颜色矩阵M1

除此之外,也可以通过直接对颜色值乘以某一系数而达到改变颜色分量的目的。如图5所示的颜色矩阵M2,将绿色分量放大了2倍,这样的效果就是图片泛绿色。
颜色矩阵M2
图5 颜色矩阵M2

————以上内容收集于网络:http://www.android100.org/html/201406/05/19490.html———-


使用ColorMatrix改变图片颜色的步骤

  • 通过Bitmap.createBitmap()方法获得一个空白的Bitmap对象。
  • 使用Bitmap对象创建画布Canvas, 然后创建画笔Paint。
  • 定义ColorMatrix,并指定RGBA矩阵。
  • 使用ColorMatrix创建一个ColorMatrixColorFilter对象, 作为画笔的滤镜 paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix))。
  • 使用Canvas.drawBitmap()方法把原图使用定义的Paint画到空白的Bitmap对象上即可获得改变RGBA值后的图像。

图像颜色处理实例

  • 首先准备一张用来修改颜色的黑色原始图片 btn_pause.png 如下:
    这里写图片描述

  • 布局文件 colormatrix_activity.xml 内容如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="R" />

    <SeekBar
        android:id="@+id/sb_red"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="0" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="G" />

    <SeekBar
        android:id="@+id/sb_green"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="0" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="B" />

    <SeekBar
        android:id="@+id/sb_blue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="0" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="A" />

    <SeekBar
        android:id="@+id/sb_alpha"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="255" />

    <ImageView
        android:id="@+id/iv_color_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/btn_pause" />

</LinearLayout>
  • 界面代码 ColorMatrixActivity.java
/**
 * Created by lvzhengbin on 15/10/15.
 */
public class ColorMatrixActivity extends ActionBarActivity {

    private SeekBar sb_red, sb_green, sb_blue, sb_alpha;
    private ImageView iv_show;
    private Bitmap afterBitmap;
    private Paint paint;
    private Canvas canvas;
    private Bitmap baseBitmap;

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

    private void initView() {
        iv_show = (ImageView) findViewById(R.id.iv_color_show);
        sb_red = (SeekBar) findViewById(R.id.sb_red);
        sb_green = (SeekBar) findViewById(R.id.sb_green);
        sb_blue = (SeekBar) findViewById(R.id.sb_blue);
        sb_alpha = (SeekBar) findViewById(R.id.sb_alpha);

        sb_red.setOnSeekBarChangeListener(seekBarChange);
        sb_green.setOnSeekBarChangeListener(seekBarChange);
        sb_blue.setOnSeekBarChangeListener(seekBarChange);
        sb_alpha.setOnSeekBarChangeListener(seekBarChange);

        baseBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.btn_pause);
        // 1.获取一个与baseBitmap大小一致的可编辑的空图片
        afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth(),
                baseBitmap.getHeight(), baseBitmap.getConfig());
        // 2.使用Bitmap对象创建画布Canvas, 然后创建画笔Paint。
        canvas = new Canvas(afterBitmap);
        paint = new Paint();
    }

    private SeekBar.OnSeekBarChangeListener seekBarChange = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            if(seekBar.getId() == R.id.sb_alpha){
                iv_show.getDrawable().setAlpha(sb_alpha.getProgress());

            }else{
                float progressR = sb_red.getProgress();
                float progressG = sb_green.getProgress();
                float progressB = sb_blue.getProgress();
                // 根据SeekBar定义RGBA的矩阵, 通过修改矩阵第五列颜色的偏移量改变图片的颜色
                float[] src = new float[]{
                        1, 0, 0, 0, progressR,
                        0, 1, 0, 0, progressG,
                        0, 0, 1, 0, progressB,
                        0, 0, 0, 1, 0};

                // 3.定义ColorMatrix,并指定RGBA矩阵
                ColorMatrix colorMatrix = new ColorMatrix();
                colorMatrix.set(src);
                // 4.使用ColorMatrix创建一个ColorMatrixColorFilter对象, 作为画笔的滤镜, 设置Paint的颜色
                paint.setColorFilter(new ColorMatrixColorFilter(src));
                // 5.通过指定了RGBA矩阵的Paint把原图画到空白图片上
                canvas.drawBitmap(baseBitmap, new Matrix(), paint);
                iv_show.setImageBitmap(afterBitmap);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
        }
    };
}
  • 我们可以通过SeekBar调节RGB的值来修改图片的颜色来达到不同的效果,运行效果如下:
    这里写图片描述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 使用ColorMatrix改变图片颜色 的相关文章

  • Android Room ORM:支持 SQLite 的自定义构建

    我需要使用 SQLite 的自定义构建 基于 sqlite org 版本https sqlite org android doc trunk www index wiki https sqlite org android doc trunk
  • 使用 ActiveAndroid 库存储 HashMap

    我有一堂课 Table name Control public class Control extends Model Column private String name Column private Map
  • 使用 NEON 内在函数除以浮点数

    我当时正在处理四个像素的图像 这是在armv7对于 Android 应用程序 我想分一个float32x4 t向量由另一个向量组成 但其中的数字与大约不同0 7 to 3 85 在我看来 除法的唯一方法是使用右移 但这是针对一个数字2 n
  • Android版本App更新代码

    我读到如果我们想更新Google Play中的应用程序 版本代码应该高于以前的apk文件 我有一个版本代码为 20 且版本名称为 1 0 的应用程序 那么要更新app 应该如何增加版本号呢 应该增加10吗 或者仅仅 1 就足够了 即版本代码
  • Android 从 C++ 端播放原始音频

    我需要能够在 Android 系统的 C 端以自定义文件格式传输音频 我正在致力于移植自定义媒体播放器 并且需要能够打开自定义文件并从中传输音频 这很重要 因为我认为从性能角度来看将整个播放器移植到 JAVA 是不可行的 并且通过 JNI
  • 如何在 M1 Mac 上运行的模拟器上运行旧版 Android 版本(例如 API 级别 21)?

    虽然现在有一个适用于 M1 mac 的 Android Studio 和支持arm架构的Android模拟器镜像 https stackoverflow com questions 64907154 android studio emula
  • Auto-value-gson出现接口错误,注册一个InstanceCreator?

    我有一个如下所示的接口类 public interface Species String name And a Human实现的类 AutoValue使用类型适配器 AutoValue public abstract class Human
  • 片段内容下方是否存在持久性 BottomSheet?

    Using a 持久底表 https material google com components bottom sheets html bottom sheets persistent bottom sheets 在一个协调器布局 htt
  • Monodroid 示例/带有源代码的小部件

    我是一名 NET 开发人员 我对用 C 开发 Android 应用程序感兴趣 并且我得到了 monodroid 是否有任何来源可以让我获得 monodroid 示例应用程序 带有源代码 这将帮助我在 monodroid 中开发应用程序 或者
  • TextView 宽度匹配drawableTop 宽度

    有什么办法可以使TextView width匹配复合可绘制宽度 XML 例如对于 xml 代码
  • 警报对话框中的 Webview 不显示内容

    我正在开发一个 Android 应用程序 我需要在网络视图和警报对话框上显示一个网站 该站点显示在网络视图中 但不显示在警报对话框中 到目前为止 这是我的代码 WebView WebView myWebView WebView v find
  • Android Gradle 问题 - Flutter / Dart

    我的 Gradle 同步有问题 我使用 IntelliJ 和 Android Studio 构建 Flutter Dart 应用程序 我添加了 2 个新的依赖项 现在 Gradle 出现了问题 在 Android Studio 中一切正常
  • Android 无法解析日期异常

    当尝试解析发送到我的 Android 客户端的日期字符串时 我得到一个无法解析的日期 这是例外 java text ParseException 无法解析的日期 2018 09 18T00 00 00Z 位于 偏移量 19 在 java t
  • 将人类日期(当地时间 GMT)转​​换为日期

    我正在服务器上工作 服务器正在向我发送 GMT 本地日期的日期 例如Fri Jun 22 09 29 29 NPT 2018在字符串格式上 我将其转换为日期 如下所示 SimpleDateFormat simpleDateFormat ne
  • 为什么 Google 建议将库复制到您的树中?

    谷歌的Play 服务 API 的使用说明 http developer android com google play services setup html 例如 说 将 extras google google play service
  • 在android中从SD卡上传图像到facebook

    我无法从 SD 卡上传 Facebook 上的图像 我使用了下面的代码 但它没有给我错误 但同时它没有上传图像 byte data null try FileInputStream fis new FileInputStream filep
  • React Native HTTPS Api 调用在 IOS 中有效,但在 Android 中无效

    所以基本上我所做的就是简单地对启用了 HTTPS 的 UAT 服务器进行简单的 Axios 调用 我已经在 IOS 中测试了整个应用程序 API 调用工作正常 但一旦我在 Android 中测试了相同的应用程序 在真正的 Android 设
  • JetPack Compose - 卡中行中的weight() 不起作用

    创建 Android 应用程序时 我将一些可组合项放在卡片的一行中 如下所示 但它没有按我的预期工作 我添加 weight 1f 的可组合项不再显示 data class Test val title String val text Str
  • Android Espresso 单击按钮时出现错误

    我正在尝试使用 espresso 框架为 Android 应用程序编写一些 UI 测试 现在我只是检查启动屏幕上是否存在所有元素 然后尝试单击登录按钮 单击按钮时 测试由于错误而失败 我似乎无法理解为什么会发生这种情况 我的测试代码是 Ru
  • View.post(),以及当Runnables被执行时

    我最初的问题是需要知道我的根的高度和宽度View这样我就可以进行程序化的布局更改 就我的目的而言 我不一定需要在onCreate 对于我来说 以编程方式添加我的孩子就足够了View根布局完成后 因此我很乐意使用onWindowFocusCh

随机推荐

  • 大一C语言入门到底怎么学

    大一C语言入门到底怎么学 大一C语言入门按照下面路线来 xff0c 以及把下面的100道C语言编程案例学会就入门啦 xff5e 入门篇 1 什么是计算机语言 2 C语言的程序的结构 3 运行C语言的步骤与方法 4 了解简单的算法 5 怎么表
  • BW性能监控利器——ST13总结

    题记 xff1a BW 的小工具 xff0c ST13 xff0c 近来每每使用 xff0c 都颇有感慨 xff0c 故总结如下 xff0c 以备后用 1 Process Chain xff1a ST13 gt BW TOOLS gt Pr
  • 你见过的最差的程序员是怎样的?

    你见过的最差的程序员是怎样的 xff1f 公司来了个应届生 xff0c 让我来带 得 我成了保姆 xff0c 百度一下就能找到答案的事 xff0c 非得让我手把手的教 终于有一天 xff0c 我忍不住了 xff0c 说了他一顿 xff0c
  • 大龄程序员都去哪了?

    大龄程序员都去哪了 xff1f 大龄程序员依然在各个大中小公司正常工作 外资 国企不说了 xff0c 30 40岁的员工很多很多 xff0c 不仅仅是程序员 xff0c 产品啊 xff0c 测试 xff0c 运维 不仅仅喝计算机有关系的 x
  • 学习Java——枚举

    目录 枚举的用法 定义 特点 应用场景 总结 用法 常量 switch 向枚举中添加新方法 覆盖枚举的方法 实现接口 使用接口组织枚举 每日寄语 枚举的用法 在 span style background color d7d8d9 java
  • Docker镜像、容器操作

    文章目录 一 Docker镜像操作1 搜索镜像2 获取镜像3 查看镜像查看下载到本地的所有镜像查看下载的镜像文件信息查看镜像详细信息 4 为本地的镜像添加新的标签5 镜像导出导入到本地导出镜像 xff0c 将镜像保存为本地文件导入镜像 xf
  • Windows系统中gvim永久配置行号和背景颜色

    1 gvim永久配置 1 永久配置行号 点击编辑 启动设定 如下图所示 在下图画框位置输入set number保存即可 2 xff09 永久设置背景颜色 首先应该知道都有什么颜色 xff0c 可以设置的颜色按照下图查看 比如现在我要设置背景
  • UKF无迹卡尔曼滤波

    UKF无迹卡尔曼滤波是在卡尔曼滤波和变换的基础上发展而来的 xff0c 它是利用无损变换使线性假设下的卡尔曼滤波应用于非线性系统 之前提到的EKF算法简单易操作 xff0c 在工业中有广泛的应用 但是它也存在很多缺点 xff1a 需要计算非
  • 在失望中重找希望——我的2013年工作总结

    时间过的真的是快 来广州已整整工作了一年啦 从2012年长沙工作离职后 为了我的女朋友 我毅然踏上了南下广州的征途 来到羊城后 很快 xff0c 一个礼拜就找到了现在工作的这家公司 现在回想一下 真觉得当初没有好好斟酌一下 2013年里 x
  • 使用eclipse 4.3 经常出现卡死、无响应情况的解决方法

    最近在使用 eclipse 4 3 开发的时候 xff0c 经常出现卡死 无响应 情况 在网上搜索了一下之后发现 xff0c 发现网上还是有解决方法的 于是以记之 xff01 一 首先 xff0c 我们修改下eclipse的内存配置文件 l
  • Android学习之 移动应用<App>微信支付集成小结

    微信支付现在主要集成在 xff1a 1 移动应用开发 2 网站应用开发 3 公众账号开发 本篇主要针对移动应用App集成微信支付 xff0c 实际项目坑点分享 xff01 一 既予之 与共之 xff1a 平台资源 1 微信开放平台 xff1
  • Android学习之 主项目合并Library子项目中的Manifest

    一 项目背景 xff1a 项目XX是一个按模块化规则来进行开发的 xff0c 包含主模块A 子模块B 子模块C 子模块D xff0c 其中子模块B C D都是Library项目 xff0c 并且都包含有自己的Actity等资源文件 Andr
  • 我的2011——周年纪

    今天距我开博的日期 xff0c 有将近一年半的时间 xff0c 博客的确是一个会让我们有所期待的东西 xff0c 学习 积累 沉淀 再学习 2011年 xff0c 经历了血雨腥风的SAP市场开始主推云存储和内存运算 xff0c HANA在不
  • Android学习之 Manifest中meta-data扩展元素数据的配置与获取

    在AndroidManifest xml清单文件中 我们有时会看到如下类似的 lt meta data gt 元素开始的配置内容 xff1a lt meta data android name 61 34 com google androi
  • 工具使用之 adbWireless无线调试Android应用

    今天巧遇这个工具 xff1a adbwireless apk xff0c 于是乎 试爽了一把 xff0c 果然觉得是个不错的工具 可谓是相见恨晚 可以帮助Android开发的同事们实现手机无线调试应用程序 对 xff01 你没有听错 如果你
  • Android系统 小米/三星/索尼 应用启动图标未读消息数(BadgeNumber)动态提醒

    在Android手机上 xff0c 如QQ 微信当有未读消息的时候 我们可以看到在应用的启动图标的右上角会有一个红色圈圈 且圈圈里会动态显示未读消息的数目 xff0c 如下图显示 xff1a 那么该功能是怎么实现的呢 xff1f 在万能的互
  • 工具使用之Android Studio快捷键-mac版

    最近给自己添置了一台mac 也算是完成了多年前的一个小愿望 做为Android开发者的我于是搭载了Android Studio 1 1正式版做为了我的安卓开发工具 在window上eclipse我可以畅快的玩耍 xff0c idea和as也
  • Android学习之 Scroller的介绍与使用

    类概述 Android里Scroller类是为了实现View平滑滚动的一个Helper类 通常在自定义的View时使用 xff0c 在View中定义一个私有成员mScroller 61 new Scroller context 设置mScr
  • Android 从外部网页拉起跳转到App

    业务场景 当需要从外部第三方网页中通过点击某个链接或按钮启动App应用程序 实现 新建demo工程 xff0c 并实现一个Activity xff0c 用来接收从外部跳转传入的信息 代码如下 xff1a span class hljs ke
  • Android 使用ColorMatrix改变图片颜色

    ColorMatrix的颜色矩阵介绍 颜色矩阵M是一个5 4的矩阵 xff0c 在Android中 xff0c 颜色矩阵M是以一维数组m 61 a b c d e f g h i j k l m n o p q r s t 的方式进行存储的