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

简介: 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是需要设置该像素值为哪个颜色,下面我们来看一张图片,如下图所示:

40.png

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


让图片变得更鲜艳


首先我们需要定义两个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。

41.png

这里你也可以通过遍历判断所有像素点哪个颜色值更高,然后统计分别自加计算红绿蓝最高的数值各有多少,然后再遍历一次单独给最高最多的颜色设置值,以达到让某图片最多的颜色更鲜艳的目的。


给图片添加水印


下面我们来实现大多数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;//返回水印图片
}


代码注释已经非常详细了,这里就是简单的叠加绘制流程,创建一个空白位图,先画源图像,再在右下角画水印图像即可,详细的计算看下图就明白了:

42.png

接着我们还需要创建一个ImageView放置水印图像,这里的XML代码就不写了,和上面差不多,除了Id不同之外,其他的设置调用代码如下:

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


这样我们就实现了给图片添加水印的效果,实现的效果如下图所示:

43.png

本文的实现代码以及上篇文章的实现代码Github下载地址:点击下载

相关文章
|
2月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
21天前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
|
3月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
75 20
Android经典面试题之图片Bitmap怎么做优化
|
2月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件基础与进阶
【10月更文挑战第5天】在Android应用开发中,自定义控件是提升用户体验和界面个性化的重要手段。本文将通过浅显易懂的语言和实例,引导你了解自定义控件的基本概念、创建流程以及高级应用技巧,帮助你在开发过程中更好地掌握自定义控件的使用和优化。
52 10
|
1月前
|
前端开发 Android开发 UED
安卓应用开发中的自定义控件实践
【10月更文挑战第35天】在移动应用开发中,自定义控件是提升用户体验、增强界面表现力的重要手段。本文将通过一个安卓自定义控件的创建过程,展示如何从零开始构建一个具有交互功能的自定义视图。我们将探索关键概念和步骤,包括继承View类、处理测量与布局、绘制以及事件处理。最终,我们将实现一个简单的圆形进度条,并分析其性能优化。
|
2月前
|
前端开发 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的世界里,自定义控件如同画家的画笔,能够绘制出独一无二的界面。通过掌握自定义控件的绘制技巧,开发者可以突破系统提供的界面元素限制,创造出既符合品牌形象又提供卓越用户体验的应用。本文将引导你了解自定义控件的核心概念,并通过一个简单的例子展示如何实现一个基本的自定义控件,让你的安卓应用在视觉和交互上与众不同。
|
3月前
|
缓存 前端开发 Android开发
安卓应用开发中的自定义控件
【9月更文挑战第28天】在安卓应用开发中,自定义控件是提升用户界面和交互体验的关键。本文通过介绍如何从零开始构建一个自定义控件,旨在帮助开发者理解并掌握自定义控件的创建过程。内容将涵盖设计思路、实现方法以及性能优化,确保开发者能够有效地集成或扩展现有控件功能,打造独特且高效的用户界面。
|
3月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义控件
【9月更文挑战第5天】在安卓开发的海洋中,自定义控件如同一艘精致的小船,让开发者能够乘风破浪,创造出既独特又高效的用户界面。本文将带你领略自定义控件的魅力,从基础概念到实战应用,一步步深入理解并掌握这一技术。
|
3月前
|
Android开发
Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果
本文介绍了 `SpannableString` 在 Android 开发中的强大功能,包括如何在单个字符串中应用多种样式,如颜色、字体大小、风格等,并提供了详细代码示例,展示如何设置文本颜色、添加点击事件等,助你实现丰富文本效果。
312 3
|
4月前
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。