Android自定义控件(九)——如何让图片颜色更鲜艳以及给图片添加水印

Bitmap像素是否可以更改

在前面一节中,我们详细介绍了两种创建Bitmap的方式,一种是使用BitmapFactory,一种是使用Bitmap静态方法,但这里我有一个需求,假如我有一张图片,绿色的颜色非常丰富,但绿色很暗,这个时候我想要修改该图片每个像素中的绿色值,用这两种方式创建的Bitmap都能直接修改吗?

答案是否定的,所有使用 BitmapFactory创建的Bitmap都是不可更改其像素值的,只有通过Bitmap以下几种函数创建的Bitmap才能完成如上需求,代码如下:

#只有这三个方法生成的Bitmap可以进行像素更改操作
copy(Bitmap.Config config,boolean isMutable)
createBitmap(int width,int height,Bitmap.Config config)
createScaledBitmap(Bitmap src,int dstWidth,int dstHeight,boolean filter)

不过我们这里需要注意的一点是,使用createScaledBitmap创建Bitmap时,如果源图像的宽高与生成图像的宽高一致,那么会直接返回源图像,不会生成新的图像,如果源图像不可更改,那么新图像也不可更改,如果源图像可以更改,那么新图像也可以更改。

Copy()函数

今天我们的实现主要用的就是Copy()函数,所以我们需要重点来讲解以下,这个函数,我们先来看看这个函数的定义:

copy(Bitmap.Config config,boolean isMutable)

Config config:像素在内存中的存储格式,取值有ARGB_8888等四个值,不知道的可以返回小编上一篇的博文。

boolean isMutable:新创建的Bitmap是否可以更改其中的像素。

该函数的意思时根据源图像创建一个副本,但可以指定副本的像素存储格式,同时可以自己定义是否可以更改其像素值。

setPixel(),getPixel()

因为要更改某图片的像素值,所以必须要用到这两个设置,和获取像素值的函数,他们的定义如下:

public void setPixel(int x,int y,int color)
public void getPixel(int x,int y)

很明显,x,y是获取某图片像素点的坐标值,color是需要设置该像素值为哪个颜色,下面我们来看一张图片,如下图所示:

源图片我们可以看到这张图片的绿色草坪,颜色有点偏暗,所以我们接下来需要通过上面讲解的所有函数,把图片的绿色变得更亮。

让图片变得更鲜艳

首先我们需要定义两个ImageView,方便后续进行对比,一个直接显示源图像,一个后续进行设置,XML代码如下:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/dog"/>

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

定义好之后,我们直接在主Activity中获取到id为imageview的控件,然后首先使用copy()函数进行复制一张可以编辑像素的Bitmap,代码如下:

this.imageView=(ImageView) findViewById(R.id.imageview);//获取控件
Bitmap srcBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.dog);//获取源图片,srcBitmap不可编辑像素
Bitmap dstBitmap=srcBitmap.copy(Bitmap.Config.ARGB_8888,true);copy后设置true,dstBitmap就是可以设置像素的Bitmap

这里我们获取到了可编辑Bitmap后,下面直接遍历该bitmap每个像素值,然后获取到颜色值,进行对比,在调升我们每个像素的绿色比重,代码如下:

for(int h=0;h<srcBitmap.getHeight();h++){// 行
    for(int w=0;w<srcBitmap.getWidth();w++){//列
        int pixel=srcBitmap.getPixel(w,h);//获取该点像素值
        int red= Color.red(pixel);//获取该点像素值的红色值
        int alpha= Color.alpha(pixel);//获取该点像素值的透明值
       	int green= Color.green(pixel);//获取该点像素值的蓝色值
        int blue= Color.blue(pixel);//获取该点像素值的绿色值
		if(green<200){//当绿色小于200,最高255
			green+=50;//加50
		}
		dstBitmap.setPixel(w,h,Color.argb(alpha,red,green,blue));//然后修改该dstBitmap该点像素值
	}
}
this.imageView.setImageBitmap(dstBitmap);//设置到iamgeview控件中

这里的代码很好理解,就是遍历获取每个像素值,然后获取该像素值的红,蓝,绿以及透明度的值,当绿色值小于200的时候,更改绿色值,然后设置到可以更改颜色的dstBitmap中。

备注:这里有一点需要主要,为什么需要判断小于200才能加50呢?我们都知道ARGB_8888颜色值的最大值是255,假如现在有个颜色值是250,你不小心也加了50,那么就是300,那么程序会设置300吗?不会,那么程序会自动向下取整吗?也不会,颜色值计算是取余的,也就是说,假如你更改了某个颜色值为300,那么它只会设置成45,并不会设置成你希望的255。
更改颜色后的对比图
这里你也可以通过遍历判断所有像素点哪个颜色值更高,然后统计分别自加计算红绿蓝最高的数值各有多少,然后再遍历一次单独给最高最多的颜色设置值,以达到让某图片最多的颜色更鲜艳的目的。

给图片添加水印

下面我们来实现大多数APP经常使用到的功能给图片添加水印,其实代码很简单,我们来看看这段代码:

/***
* 添加水印
* @param srcBitmap源图像
* @param watermark水印图像
* @return
*/
private Bitmap createWaterMarkBitmap(Bitmap srcBitmap, Bitmap watermark){
	if(srcBitmap==null){
	return null;
	}
	int srcWidth=srcBitmap.getWidth();//获取源图像的宽
	int srcHeight=srcBitmap.getHeight();//获取源图像的高
	int waterWidth=watermark.getWidth();//获取水印图像的宽
	int waterHeight=watermark.getHeight();//获取水印图像的高
	Bitmap bitmap=Bitmap.createBitmap(srcWidth,srcHeight,Bitmap.Config.ARGB_8888);//创建一个空白位图
	Canvas canvas=new Canvas(bitmap);//根据位图创建画布
	canvas.drawBitmap(srcBitmap,0,0,null);//先画出源图像
	canvas.drawBitmap(watermark,srcWidth-waterWidth+5,srcHeight-waterHeight+5,null);//然后在画水印图像
	return bitmap;//返回水印图片
}

代码注释已经非常详细了,这里就是简单的叠加绘制流程,创建一个空白位图,先画源图像,再在右下角画水印图像即可,详细的计算看下图就明白了:
水印计算图接着我们还需要创建一个ImageView放置水印图像,这里的XML代码就不写了,和上面差不多,除了Id不同之外,其他的设置调用代码如下:

this.imageView2=(ImageView)findViewById(R.id.imageview2);
this.imageView2.setImageBitmap(createWaterMarkBitmap(dstBitmap,BitmapFactory.decodeResource(getResources(),R.drawable.water)));

这样我们就实现了给图片添加水印的效果,实现的效果如下图所示:
添加水印效果
本文的实现代码以及上篇文章的实现代码Github下载地址:点击下载

发布了92 篇原创文章 · 获赞 110 · 访问量 72万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览