需求背景分析:

产品和美工给了个根据专辑封面取主题色做背景,并且专辑封面还要融入背景的效果图,一开始看到取色觉得简单啊,不就是之前看过的palette嘛,可是专辑封面渐变消失融入背景怎么做呢,我们一步步分析。

1. 首先是背景取色,Palette

这个比较简单,因为已经有现成的API让我们调用

Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {

@Override

public void onGenerated(Palette palette) {

//todo

}

}

});

palette可以获取到6种颜色,而且palette还有其他功能,这里就不介绍了,网上有很多案例,我们继续。

因为背景色是渐变的,由深变浅,所以要这里取出两个颜色通过paint的shader绘制一张渐变效果的bitmap,具体代码如下

//......省略一些

Palette.from(resource).generate(new Palette.PaletteAsyncListener() {

@Override

public void onGenerated(Palette palette) {

//记得判空

if(palette==null)return;

//palette取色不一定取得到某些特定的颜色,这里通过取多种颜色来避免取不到颜色的情况

if (palette.getDarkVibrantColor(Color.TRANSPARENT) != Color.TRANSPARENT) {

createLinearGradientBitmap(palette.getDarkVibrantColor(Color.TRANSPARENT), palette.getVibrantColor(Color.TRANSPARENT));

} else if (palette.getDarkMutedColor(Color.TRANSPARENT) != Color.TRANSPARENT) {

createLinearGradientBitmap(palette.getDarkMutedColor(Color.TRANSPARENT), palette.getMutedColor(Color.TRANSPARENT));

} else {

createLinearGradientBitmap(palette.getLightMutedColor(Color.TRANSPARENT), palette.getLightVibrantColor(Color.TRANSPARENT));

}

}

});

//创建线性渐变背景色

private void createLinearGradientBitmap(int darkColor,int color) {

int bgColors[] = new int[2];

bgColors[0] = darkColor;

bgColors[1] = color;

if(bgBitmap==null){

bgBitmap= Bitmap.createBitmap(ivBg.getWidth(),ivBg.getHeight(), Bitmap.Config.ARGB_4444);

}

if(mCanvas==null){

mCanvas=new Canvas();

}

if(mPaint==null){

mPaint=new Paint();

}

mCanvas.setBitmap(bgBitmap);

mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

LinearGradient gradient=new LinearGradient(0, 0, 0, bgBitmap.getHeight(),bgColors[0],bgColors[1], Shader.TileMode.CLAMP);

mPaint.setShader(gradient);

RectF rectF=new RectF(0,0,bgBitmap.getWidth(),bgBitmap.getHeight());

// mCanvas.drawRoundRect(rectF,16,16,mPaint); 这个用来绘制圆角的哈

mCanvas.drawRect(rectF,mPaint);

ivBg.setImageBitmap(bgBitmap);

}

先给大家看看目前效果,免得枯燥

image.png

image.png

ok,目前背景色就实现到这了

2. 接着是最蛋疼的让他渐变融入到背景色中了

我目前有两种思路(两种我都用过了,推荐第二种)

思路

优点

缺点

在图片上面叠加一层颜色渐变的图片

方便简单,只需多加一个控件

需要获取旁边背景色对应的颜色值,这个比较难,而且我目前才用的算法获得有时候不准确

通过修改图片的透明度来达到渐变效果

无需计算旁边颜色,最终效果较佳

图片较大时,计算量比较大,速度较慢

ok,由于我最后还是采用了第二种,这里就只介绍第二种方法了,思路很简单,就是获取图片的bitmap数组,通过遍历来判断修改相应的透明度,具体代码如下:

//修改透明度

public static Bitmap getImageToChange(Bitmap mBitmap) {

Log.d(TAG,"with="+mBitmap.getWidth()+"--height="+mBitmap.getHeight());

Bitmap createBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_4444);

int mWidth = mBitmap.getWidth();

int mHeight = mBitmap.getHeight();

for (int i = 0; i < mHeight; i++) {

for (int j = 0; j < mWidth; j++) {

int color = mBitmap.getPixel(j, i);

int g = Color.green(color);

int r = Color.red(color);

int b = Color.blue(color);

int a = Color.alpha(color);

float index=i*1.0f/mHeight;

if(index>0.5f ){

float temp=i-mHeight/2.0f;

a= 255-(int) (temp/375*255);

}

color = Color.argb(a, r, g, b);

createBitmap.setPixel(j, i, color);

}

}

return createBitmap;

}

(ps:代码中采用的一些宽高和数值,要看具体效果来设置,这里仅做参考!)

2.1 增加一种修改透明度的方法

该算法使用位移和模运算来单独修改透明值,不用把ARGB的四个颜色都取出来,会比之前的速度快很多

//透明渐变

int[] argb=new int[ALBUM_SIZE*ALBUM_SIZE];

localBitmap.getPixels(argb, 0, localBitmap.getWidth(), 0, 0, localBitmap.getWidth(), localBitmap.getHeight());

//循环开始的下标,设置从什么时候开始改变

int start = argb.length / 2;

int mid = argb.length * 83 / 100;

int lines = ((mid - start) / localBitmap.getHeight()) + 2;

int width = localBitmap.getWidth();

for (int i = 0; i < lines; i++) {

for (int j = 0; j < width; j++) {

int index = start - width + i * width + j;

//由于默认图片透明色为0,所以要增加判断,不然后续处理的颜色会变为黑色

if(argb[index]!=0){

argb[index] = ((int) ((1 - ((float) i / lines)) * 255) << 24) | (argb[index] & 0x00FFFFFF);

}

}

}

for (int i = mid; i < argb.length; i++) {

argb[i] = (argb[i] & 0x00FFFFFF);

}

localBitmap = Bitmap.createBitmap(argb, localBitmap.getWidth(), localBitmap.getHeight(), Bitmap.Config.ARGB_8888);

(ps:算法中的数值也是仅供参考,具体还要看自己想要实现的效果,比如 <<24 和 0x00FFFFFF 是由于bitmap采用Config.ARGB_8888,大家根据自身需求修改就好,这里只提供思路)

2.2 适配图片透明处理

对于原图中带有透明的情况,获取像素点的时候透明的位置颜色值为0,所以在做透明渐变的时候要判断一下,避免后续颜色变成黑色

if(argb[index]!=0){

argb[index] = ((int) ((1 - ((float) i / lines)) * 255) << 24) | (argb[index] & 0x00FFFFFF);

}

最终效果如下:

image.png

image.png

总结

本次内容不难,重要是实现思路,我一开始采用第一种叠加图片的方法,寻找计算线性渐变某一位置的值,后来找到了但最终效果不如上述的第二种方法,但是我发现第二种方法在计算比较大的Bitmap的时候速度是真很慢的(遍历一个Bitmap数组,脑壳痛),所以具体还是看大家的需求吧

(ps:好久没写过文章了啊,自今年毕业来就一直忙东忙西,终于有点时间写东西了 TAT)

Demo地址:

android获取图片背景色,android案例--图片取色并让图片融入背景色相关推荐

  1. android获取键盘状态,Android获取屏幕方向及键盘状态的小例子

    Android获取屏幕方向及键盘状态的小例子 复制代码 代码如下: Configuration config = getResources().getConfiguration(); if (conf ...

  2. android获取网络图片方法,Android获取网络图片并显示的方法

    本文实例为大家分享了Android获取网络图片并显示的具体代码,供大家参考,具体内容如下 使用 HttpURLConnection 获得连接,再使用 InputStream 获得图片的数据流,通过 B ...

  3. android+获取相册列表,android 获取相册列表的实现(二)

    该项目实现的功能如下: 获取手机相册,点击每个相册之后进入该相册的图片列表界面,在图片列表界面可以实现图片多选,然后进入所选择的图片界面,在该界面内可 该项目实现的功能如下: 获取手机相册,点击每个相 ...

  4. android获取activity截图,Android Activity 不能被截屏的解决方法

    Android Activity 不能被截屏的解决方法 在Activity 添加即可 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECU ...

  5. android 获取相机方向,android – 从相机捕捉图像,导致炸毁方向

    我试图从相机捕捉图像,它可以在横向模式下正常工作,当我拍摄肖像时,它会旋转.以下是我使用的代码: BitmapFactory.Options bounds = new BitmapFactory.Op ...

  6. android 获取当前画布,Android硬件位图填坑之获取硬件画布

    前言 Hardware Bitmap(硬件位图)是Android8.0加入的新功能,通过设置Bitmap的config为Bitmap.Config.HARDWARE,创建所谓的Hardware Bit ...

  7. Android获取Linux图像信息,Android系统信息获取 之十三:Linux内核版本信息获取

    Android系统信息获取 之十三:Linux内核版本信息获取 Android系统是基于Linux的,各个Android版本对应的Linux版本不尽相同,我们这里不去追究各个Android对应的Lin ...

  8. android 获取对话框对象,Android 基本Dialog和自定义Dialog

    Android 基本Dialog和自定义Dialog Dialog类是对话框的基类,但你应该避免直接实例化Dialog ,可以使用子类 1.AlertDialog 此对话框可以显示标题,最多三个按钮, ...

  9. android获取程序名称,Android获取应用程序名称(ApplicationName)示例

    MainActivity如下: 代码如下: package cn.testapplicationname; import android.os.Bundle; import android.widge ...

  10. android获取详细地址,Android获取当前子网掩码地址(亲测可用)

    Android 获取当前子网掩码地址(亲测可用),现在网上好多都是通过 DhcpInfo 来获取,但是通过这种方法有 Bug,很多人用 DhcpInfo 的方式都是获取不到,都是为 0.0.0.0. ...

最新文章

  1. JGG:微生物组学专刊(赵方庆、白洋、张志刚、王军、郑钜圣、魏泓、沈伟、刘永鑫等)...
  2. 安装pr_PR 一键转场插件 安装教程
  3. 数据库:redis和MySQL如何做到数据的一致性?
  4. matlab 二维高斯滤波 傅里叶_光电图像处理 | 傅里叶变换(二)
  5. SpringSecurity集中式整合之加入jsp
  6. 林海峰老师python课件密码
  7. kettle-执行结果
  8. x264源代码简单分析:滤波(Filter)部分
  9. java 发送信号_java – 在Windows中发送任意信号?
  10. Linux sed命令之删除文件第一行,第n行
  11. Warship+NPOI导入导出组件介绍【对象化】
  12. 阿里云分布式架构云平台解决方案
  13. T410i笔记本DP线转接HDMI链接外设无法传输声音问题解决
  14. lambda x:x*x
  15. C语言 日历查询系统 成品
  16. 苹果闭门造车6年了!是否已经“翻车”?
  17. leetcode 37 数独问题的解答
  18. hnust 2186 C 层次遍历
  19. 编译基于obs-studio的阿里巴巴直播工具tblive的过程和常见问题解决
  20. 建仓类型与对应建仓价MT4

热门文章

  1. 计算机排版原理,课后作文的计算机排版原理.ppt
  2. 华为设备配置HoVPN
  3. 【计算机基础复习】计算机组成原理
  4. java跟父母固定抽奖_当前一些大学生用父母辛苦劳作挣来的血汗钱追逐名牌和奢侈品,比阔气、讲排场,在消费上超出自己的承受能力,有的甚至因此负债累累。这种现象体现的是(    )错误人生观。...
  5. codeforces 1312E. Array Shrinking
  6. TPlink WR880N V3 TP9343 Openwrt 改造记录
  7. Java main方法
  8. 从Meerkat的失败、映客的走红,看直播伪风口
  9. 重视肠道微生态平衡 提升抗新冠病毒免疫力
  10. 今天你将废纸篓清理干净了吗