qq android 代码生成,Android 合成 qq 隐藏图,隐藏图生成

之前在 抖音 见过这样的视频,给某个好友发一张图片,好友看到的是第一张图片,当点开后,会出现另一张图片。。。

就像这样:

默认图片是这张:

8c83d73f6d1d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1

隐藏图片是这张

8c83d73f6d1d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2

发给好友是这样

8c83d73f6d1d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

tim 20181206165553

好友点开后是这样

8c83d73f6d1d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

tim 20181206165536

原理

png 图片是有透明度的,根据图片背景的不同,可以通过控制透过的光来显示不同的图片。

举个栗子:小时候大家可能见过那种相机胶卷,拿着这种胶卷对着阳光,可以透过阳光看到胶卷中的景象。但是不对着阳光,这张胶卷就是黑色的

再举个栗子:就像医院里面,拍的片子。医生会把片子放在白色的显示屏上,看你的x光片。

这些图像都是在光透过薄片后才显示图像的

所以当白光穿过半透明的 png 图片时,会显示灰白色,当背景是黑色时,png图片会显示灰黑色。

而图片其实是一个个的像素点组成的。每一个像素点又包含rgb三种通道。对应三原色。

把像素点想象成一个个的方块,假设现在有两个方块,一个是完全不透明的黑色方块,一个是透明的方块,当摆放方块的下方是白色的时候,人的视觉看上去就是一黑一白,当下面是黑色的时候,看上去就是两个黑色方块。

开始敲代码

省略创建项目和选择图片。等等的介绍。直接写如何实现。

遍历每一个像素点

把选中的图片转换成bitmap

val disImg: Bitmap = ImageUtil.getBitmap(displayImgPath, 640, 480)

val hideImg: Bitmap = ImageUtil.getBitmap(hideImgPath, 640, 480)

saveBitmap = ImgMixUtil.INSTANCE.CalculateHiddenImage(this@MainActivity, disImg, hideImg)

创建一张新图片

val result = Bitmap.createBitmap(f_width, f_height, Bitmap.Config.ARGB_8888);

然后遍历每一个像素点。

for (x in 0 until f_width) {

for (y in 0 until f_height) {

...

// 1.上下左右交叉排列黑白像素

val blackPixel = (x + y) % 2 == 0

...

// 2. 将彩色图片转成黑白色图片

val gray =

(Color.red(origin) * 0.3 + Color.green(origin) * 0.59 + Color.blue(origin) * 0.11).toInt()

...

if (blackPixel) {

// 3. 颜色反转

val tmpGray = 255 - gray

finalColor =

Color.argb(

tmpGray,

Color.red(Color.WHITE),

Color.green(Color.WHITE),

Color.blue(Color.WHITE)

)

}

}

}

注意点:

在遍历的时候,需要将两张图片合成,所以每隔一个像素点就要切换到另一张图片,也就是交叉排列

遍历的时候,由于打开图片的时候,qq只会有黑白两色,所以,要把图片的每一个像素转换成黑白图。

在白色背景下,需要对像素点进行颜色的反转

在将图片转换成黑白图后,把颜色的色值当做透明度,然后rgb使用纯色填充,如果要在黑色背景下显示,则使用纯白填充,白色背景显示,则使用纯黑填充。

然后将色值填充到新创建的 bitmap 中

result.setPixel(x, y, finalColor);

保存到本地

private fun saveToFile(bitmap: Bitmap) {

try {

val outputStream: FileOutputStream =

FileOutputStream(Environment.getExternalStorageDirectory().absolutePath + File.separator + "save.png")

bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)

outputStream.flush()

outputStream.close()

} catch (e: Exception) {

Log.e("save to file error:%s", Log.get(e))

}

}

注意要保存成 png 格式,因为只有png格式才能实现透明度。

如果是其它背景颜色会怎么显示?

前面说了,原理是通过控制 alpha 通道的光来显示不同的图片,那么,如果通过的不是白色,或者黑色呢?下面灰色背景下,生成的图片的显示效果

8c83d73f6d1d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

tim 20181206173649

灰色介于白色和黑色之间,所以两张图片都模糊显示了。。。

想看详细实现代码->github源码

使其支持彩色图片

其实图片是可以支持彩色的,但是由于背景只有黑白,所以,如果支持彩色, 显示效果非常不好。所以没有实现。只要修改代码中 ImgMixUtil 就可以了

原来代码:

if (blackPixel) {

val tmpGray = 255 - gray

finalColor =

Color.argb(

tmpGray,

Color.red(Color.BLACK),

Color.green(Color.BLACK),

Color.blue(Color.BLACK)

)

} else {

val tmpGray = gray

finalColor =

Color.argb(

tmpGray,

Color.red(Color.WHITE),

Color.green(Color.WHITE),

Color.blue(Color.WHITE)

)

}

修改后:

if (blackPixel) {

val tmpGray = 255 - gray

finalColor =

Color.argb(

tmpGray,

Color.red(origin),

Color.green(origin),

Color.blue(origin)

)

} else {

val tmpGray = gray

finalColor =

Color.argb(

tmpGray,

Color.red(origin),

Color.green(origin),

Color.blue(origin)

)

}

生成出来的图片效果:

8c83d73f6d1d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

12c5ed4ccc41e53fa001186cd73aaff7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值