Android 修改Bitmap 图片像素的信息 R G B 颜色值 详解

简介:
要想修改Bitmap图片的 R G B信息 首先 得先拿到这张图片每个点的Color值 然后根据这个Color值 就可以算出对应的R G B 值 我们都知道在计算机语言中在内存中加载一张图片实际上是把图片的每个点的RGB信息写入内存 如果动态的修改了这些颜色信息 那绘制出来的图片就会改变。 


修改图片的颜色值其实在很多地方都有用处,我记得以前我做J2ME游戏开发的时候 因为手机本身内存比较低 不能同时在内存中加载过多的图片 比如 在打怪的时候 玩家肯定不希望每次看到的怪物都一样 在不加大内存的情况下可以选择修改图片的R G B信息 就会给玩家耳目一新的感觉 这就是游戏调色板的原理。

接下来我介绍一下代码。下面这两张图片中的话筒图片中间的颜色是白色 在这里我动态的修改图片中间的颜色值 让它动起来。

//启动activity

package cn.m15.demo;


import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class demoActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	requestWindowFeature(Window.FEATURE_NO_TITLE);

	setContentView(R.layout.main);

    }
}
//布局文件 自定义了一个View 绘制 图片

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#888888"
    android:layout_height="150dip" android:layout_width="120dip" >  
	<cn.m15.demo.RecordingView
		android:id="@+id/uvMeter" 
		android:layout_height="wrap_content" 
		android:layout_width="wrap_content"
		android:gravity="center"
		/>
</RelativeLayout>
//自定义View

package cn.m15.demo;

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;

public class RecordingView extends View{


	Paint mPaint;

	Bitmap mBitmap;

	int mBitmapWidth = 0;
	int mBitmapHeight = 0;

	int mArrayColor[] = null;
	int mArrayColorLengh = 0;
	long startTime = 0;
	int mBackVolume = 0;

	public RecordingView(Context context) {
	    super(context);
	    init(context);

	}

	public RecordingView(Context context, AttributeSet attrs) {
	    super(context, attrs);
	    init(context);
	}

	void init(Context context) {
	    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

	    //在这里创建了一张bitmap
	    mBitmap = BitmapFactory.decodeResource(context.getResources(),
		    R.drawable.ic_vd_mic_on);
	    //将这张bitmap设置为背景图片
	    setBackgroundDrawable(new BitmapDrawable(mBitmap));

	    mBitmapWidth = mBitmap.getWidth();
	    mBitmapHeight = mBitmap.getHeight();

	    mArrayColorLengh = mBitmapWidth * mBitmapHeight;
	    mArrayColor = new int[mArrayColorLengh];
	    int count = 0;
	    for (int i = 0; i < mBitmapHeight; i++) {
		for (int j = 0; j < mBitmapWidth; j++) {
		    //获得Bitmap 图片中每一个点的color颜色值
		    int color = mBitmap.getPixel(j, i);
		    //将颜色值存在一个数组中 方便后面修改
		    mArrayColor[count] = color;
		    //如果你想做的更细致的话 可以把颜色值的R G B 拿到做响应的处理 笔者在这里就不做更多解释
		    int r = Color.red(color);
		    int g = Color.green(color);
		    int b = Color.blue(color);
		    
		    count++;
		}
	    }
	    startTime = System.currentTimeMillis();
	}

	/**
	 * 返回一个随机数
	 * 
	 * @param botton
	 * @param top
	 * @return
	 */
	int UtilRandom(int botton, int top) {
	    return ((Math.abs(new Random().nextInt()) % (top + 1 - botton)) + botton);
	}

	@Override
	protected void onDraw(Canvas canvas) {
	    super.onDraw(canvas);
	    //每隔100毫秒设置一下填充的颜色区域
	    if (System.currentTimeMillis() - startTime >= 100) {
		startTime = System.currentTimeMillis();
		setVolume(UtilRandom(0, 100));
	    }
	    
	    //用于刷新屏幕
	    invalidate();
	}

	public void setVolume(int volume) {
	    int startY = 0;
	    int endY = 0;
	    boolean isAdd = false;
	    //判断当前应该填充新区域 还是还原旧的区域 
	    if (mBackVolume > volume) {
		isAdd = false;
		startY = getValue(mBackVolume);
		endY = getValue(volume);
	    } else {
		isAdd = true;
		startY = getValue(volume);
		endY = getValue(mBackVolume);
	    }
	    //没必要每次都循环图片中的所有点,因为这样会比较耗时。
	    int count = startY * mBitmapWidth;
	    //从图片须要填充或者还原 颜色的起始点 开始 到 终点 
	    for (int i = startY; i < endY; i++) {
		for (int j = 0; j < mBitmapWidth; j++) {
		    if (isAdd) {
			//将需要填充的颜色值如果不是
			//在这说明一下 如果color 是全透明 或者全黑 返回值为 0
			//getPixel()不带透明通道 getPixel32()才带透明部分 所以全透明是0x00000000 
			//而不透明黑色是0xFF000000 如果不计算透明部分就都是0了
			int color = mBitmap.getPixel(j, i);
			if (color != 0) {
			    mBitmap.setPixel(j, i, Color.BLACK);
			}
		    } else {
			//如果是还原颜色 把现在点的颜色 赋值为之前保存颜色的数组
			mBitmap.setPixel(j, i, mArrayColor[count]);
		    }
		    count++;
		}
	    }
	    mBackVolume = volume;
	}
	
    //通过百分比 根据图片宽高算出实际填充 高度
	public int getValue(int volume) {
	    return mBitmapHeight - (mBitmapHeight * volume / 100);
	}

}


相关文章
|
3月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
68 20
Android经典面试题之图片Bitmap怎么做优化
|
2月前
|
Java Unix Linux
Android Studio中Terminal运行./gradlew clean build提示错误信息
遇到 `./gradlew clean build`命令执行出错时,首先应检查错误信息的具体内容,这通常会指向问题的根源。从权限、环境配置、依赖下载、版本兼容性到项目配置本身,逐一排查并应用相应的解决措施。记住,保持耐心,逐步解决问题,往往复杂问题都是由简单原因引起的。
278 2
|
3月前
|
Android开发
Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果
本文介绍了 `SpannableString` 在 Android 开发中的强大功能,包括如何在单个字符串中应用多种样式,如颜色、字体大小、风格等,并提供了详细代码示例,展示如何设置文本颜色、添加点击事件等,助你实现丰富文本效果。
267 3
|
4月前
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。
|
4月前
|
自然语言处理 定位技术 API
Android经典实战之如何获取图片的经纬度以及如何根据经纬度获取对应的地点名称
本文介绍如何在Android中从图片提取地理位置信息并转换为地址。首先利用`ExifInterface`获取图片内的经纬度,然后通过`Geocoder`将经纬度转为地址。注意操作需在子线程进行且考虑多语言支持。
242 4
|
4月前
|
XML 前端开发 Android开发
Android经典实战之Kotlin中实现圆角图片和圆形图片
本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。
73 0
|
6月前
|
Android开发 开发者
Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。
【6月更文挑战第26天】Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。要更改主题,首先在该文件中创建新主题,如`MyAppTheme`,覆盖所需属性。然后,在`AndroidManifest.xml`中应用主题至应用或特定Activity。运行时切换主题可通过重新设置并重启Activity实现,或使用`setTheme`和`recreate()`方法。这允许开发者定制界面并与品牌指南匹配,或提供多主题选项。
86 6
|
6月前
|
Android开发 开发者
Android UI中的Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等。要更改主题
【6月更文挑战第25天】Android UI中的Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等。要更改主题,首先在`styles.xml`中定义新主题,如`MyAppTheme`,然后在`AndroidManifest.xml`中设置`android:theme`。可应用于全局或特定Activity。运行时切换主题需重置Activity,如通过`setTheme()`和`recreate()`方法。这允许开发者定制界面以匹配品牌或用户偏好。
56 2
|
6月前
|
存储 Android开发
详细解读Android获取已安装应用信息(图标,名称,版本号,包)
详细解读Android获取已安装应用信息(图标,名称,版本号,包)
81 0