惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

文章列表

游戏玩后感:ReLief:献给亲爱的你 我的周边(谷子)分享 游戏玩后感:Kanon 简谱:致真实的你 《Rust中常见的有关生命周期的误解》学习笔记 简谱:StarMap 简谱:かく咲きたらばいと恋ひめやも 简谱:东风 简谱:无法诉说的思念 简谱:Girlish 游戏玩后感:时钟机关的Layline 简谱:风之琶音 简谱:星空的记忆 简谱:因为遇见了你 简谱:月童 番茄简谱脚本转调器 游戏玩后感:青空下的约定:Refine 游戏玩后感:在这苍穹展翅 书籍读后感:控制论与科学方法论 游戏玩后感:恋爱表达式 游戏玩后感:樱之诗 MLIR-tutorial学习笔记 游戏玩后感:潜伏之赤途 游戏玩后感:纯爱咖啡厅:帕露菲重制版 游戏玩后感:智以泪聚 游戏玩后感:初雪樱 游戏玩后感:告别回忆:从今以后 游戏玩后感:梦灯花 游戏玩后感:金辉恋曲四重奏 游戏玩后感:五彩斑斓的世界 昇腾310P使用记录 游戏玩后感:AIR 游戏玩后感:弹丸论破 游戏玩后感:流景之海的艾佩莉亚 Xilinx_HLS上板过程记录 游戏玩后感:告别回忆2 游戏玩后感:恋爱绮谭 Faiss和Rapidsai_Raft使用记录 游戏玩后感:近月少女的礼仪 游戏玩后感:樱色之云,绯色之恋 游戏玩后感:幸运草的约定 游戏玩后感:星之梦、候鸟和丸子与银河龙 游戏玩后感:白色相簿2 Windows上使用VTune分析PyTorchExtension调用的Cpp程序 SpinalHDL上板过程记录 游戏玩后感:仰望夜空的星辰 最简单的算卦方法之一:梅花易数法 游戏玩后感:苍之彼方的四重奏 krkr引擎解包工具介绍 自定义CUDA实现PyTorch算子的四种简单方法 游戏玩后感:星空的记忆 游戏玩后感:9nine 游戏玩后感:AtriMyDearMoments 游戏玩后感:极限脱出 游戏玩后感:魔女的夜宴 SSH实现多跳代理 动漫观后感:向山进发 flv重封装H264、AAC流 动漫观后感:夏日重现 CSP模板 游戏玩后感:海沙风云 动漫观后感:灵能百分百 游戏玩后感:交响乐之雨 游戏玩后感:爱上火车LastRun 游戏玩后感:LittleBustersEX 游戏玩后感:SummerPockets 游戏玩后感:逆转裁判 Ultra96V2开发板简单使用 SpinalWorkshop实验笔记(三) SpinalWorkshop实验笔记(二) SpinalWorkshop实验笔记(一) PYNQ开发板上使用USB声卡+OSS兼容层播放音频 TestOS移植K210开发板 rCore-Tutorial-Book-v3学习笔记(七) 动漫观后感:凉宫春日的忧郁 rCore-Tutorial-Book-v3学习笔记(♭七) rCore-Tutorial-Book-v3学习笔记(六) rCore-Tutorial-Book-v3学习笔记(五) rCore-Tutorial-Book-v3学习笔记(四) rCore-Tutorial-Book-v3学习笔记(三) rCore-Tutorial-Book-v3学习笔记(二) rCore-Tutorial-Book-v3学习笔记(一) 游戏玩后感:RewritePlus MIT-6.S081-2020实验(xv6-riscv64)十一:net MIT-6.S081-2020实验(xv6-riscv64)十:mmap MIT-6.S081-2020实验(xv6-riscv64)九:fs MIT-6.S081-2020实验(xv6-riscv64)八:lock MIT-6.S081-2020实验(xv6-riscv64)七:thread MIT-6.S081-2020实验(xv6-riscv64)六:cow MIT-6.S081-2020实验(xv6-riscv64)五:lazy MIT-6.S081-2020实验(xv6-riscv64)四:traps MIT-6.S081-2020实验(xv6-riscv64)三:pgtbl MIT-6.S081-2020实验(xv6-riscv64)二:syscall 动漫观后感:吹响吧上低音号 MIT-6.S081-2020实验(xv6-riscv64)一:util 快速生成网络mp4视频缩略图技术 用plantuml画图示例 Python制作字符图片 动漫观后感:命运石之门 Unity3D+Post_Processing_Stack_V2自定义后处理效果研究
QQ缩略图和大图不同实现
VnYzm · 2020-08-18 · via

背景

最近在QQ群里看见别人发一张图,缩略图看着是一个样子,但打开大图以后却发现是另一张图,仔细观察这两张图发现缩略图是白色背景,大图是黑色背景,结合缩略图所在的对话框是白色的,打开大图的UI是黑色的,很容易猜到应该是依靠透明度实现的功能,因此研究了一下怎么用代码通过将两张图片混合来构造出满足要求的图片。

思路

首先,混合的图片必须是灰度图(黑白图),理由之后再讲。灰度图的每个像素都是一个0到255的整数,分别表示从纯黑到纯白的颜色。设想要构造出的灰度图每个像素颜色为c,每个像素都有一个透明度,是一个0到1的小数,设为a。当我们将一张半透明的图片覆盖在背景上时,得到的图片每个像素的颜色既不是这个像素的本来颜色,也不是背景的颜色,而是介于这两种颜色之间的颜色,即将这两个颜色按一定比例进行混合,这个混合比例就是透明度,也称为Alpha,因此这一过程称为Alpha混合。如果设背景颜色为b,混合得到的颜色为n,则有公式: \[ n=c\times a+b\times(1-a) \] 那么,我们就可以列两个方程了: \[ n_{黑}=c\times a+0\times(1-a)=c\times a \\ n_{白}=c\times a+255\times(1-a) \] 这样,我们给出两张灰度图,它们就是我们想看到的n黑和n白,只要解出c和a,就可以构造出想要的图片了。但是这里有一个问题,因为255×(1-a)始终是大于0的,所以n白将始终大于n黑,换言之,想在白色背景下显示的图片的每个像素值必须大于想在黑色背景下显示的图片对应位置的像素值。为了满足这个需求,同时保证同一图片各个像素值的相对大小,可以将黑色背景下显示的图片的像素颜色从0-255映射到0-127,把白色背景下显示的图片的像素颜色从0-255映射到128-255,这样就可以了。映射可以这样计算: \[ n_{黑新}=n_{黑原}/2 \\ n_{白新}=128+n_{白原}/2 \] 为什么混合的图片不能是彩色图呢,彩色图的每个像素都是一个三维向量,分别表示红色的强度,蓝色的强度和绿色的强度。代入到方程中会发现n白和n黑已经变成三维向量了,但它们的差值仍是一个标量,也就是说,白色背景下显示的图片的每个像素值和黑色背景下显示的图片对应位置的像素值的红色、蓝色、绿色强度差值完全相同。如果用HSV色域来解释,就是必须保证两张图片的每个像素的色相和饱和度完全相等,只有亮度不一样,而这肯定不能保证,因此混合的图片不能是彩色图。

代码

import cv2
import numpy as np

imgb = cv2.imread('test1.png', 0)
imgw = cv2.imread('test2.png', 0)
imgb = imgb // 2
imgw = imgw // 2 + 128
a = 255 - (imgw - imgb) # 因为实际图片格式中Alpha是一个0-255的整数,所以这里计算的实际是上面公式中的a*255的值。
c = np.uint8(imgb / (a / 255 + 1e-3)) # 加1e-3防止当Alpha等于0的时候除0错误
imgn = cv2.cvtColor(c, cv2.COLOR_GRAY2BGRA)
imgn[:, :, 3] = a
cv2.imwrite('testo.png', imgn)