我正在写一个项目,我需要在网上传输一组类似的图像。为了加快速度,我想做大多数电影编解码器都会做的事情。拥有关键帧,然后发送更改。
现在,我得到的是一组BufferedImage,所以类似于文本文件,我基本上只想比较它们并发送补丁。然而,我以前从来没有真正使用过图像,所以如果我要这样做,它将是相当糟糕的。
那么,实现这样的东西的最佳方式是什么,或者已经有很好的实现了吗?
我猜将图像存储在字节数组中并对它们进行二进制比较并不是很有效。
编辑:我需要流这个图像。Edit2:这不是关于实现的细节,而是更多的是:对于算法来说,什么是最有效的想法。比如只处理5px的块,如果px只有很小的变化,眼睛不会注意到,那就不要忽略它(我可以忍受一些质量损失)
发布于 2011-08-19 11:47:46
一种简单的方法是对两个图像进行等效的XOR操作。这将显示相同的像素(将为零)和已更改的像素(非零)。
如果你不关心几乎察觉不到的差异,那么也可以使用“减法”混合,然后右移来丢弃一位或两位的差异。
然后,您可以计算边界(可能是一个简单的矩形),并且只传输增量。增量将可能包含许多零或最多字节,几乎没有最右边的差异位-即,它将具有低的“熵”,这意味着它在理论上应该是高度可压缩的,使用现代压缩算法。
在接收端,反向过程也很简单。给定增量和边界框,解压缩增量,然后将其应用(XOR,或左移,然后添加)到前一个/现有图像的受影响区域。
对于更复杂的无损方法,请查看动画GIF/PNG是如何设置动画的,以及使用什么算法来计算/编码帧之间的增量信息。例如,请参见What's the best way to make an animated GIF using an algorithm?
对于更复杂的方法,在处理真实世界的图像时,如果你愿意走有损路线-那么你已经暗示过了。了解视频编解码器如何编码/传输帧,例如MPEG Video Encoding。
不用说,因为在复杂度(编码/解码过程)和传输数据大小的减少之间存在折衷,所以您必须决定在任何一端增加的计算开销是否值得节省传输。
发布于 2011-07-08 02:00:54
您可以使用getRGB(int x, int y)遍历BufferedImage的所有像素。
for (int x = 0; x < img.getWidth(); ++x)
{
for (int y = 0; y < img.getHeight(); ++y)
{
int oldARGB = oldImg.getRGB(x, y);
int newARGB = img.getRGB(x, y);
if (oldARGB != newARGB)
{
// handle the diffrence
}
}
}发布于 2014-12-22 18:18:59
我有个想法,其实这很简单。逐个比较像素
如果像素相等,则另存为RGBA(0,0,0,0)。然后将diff存储为PNG。
这是演示结果。差异是非常小的。
堆栈溢出显示为you need at least 10 reputation to post images。所以我只能在这里张贴图片地址。
http://oi61.tinypic.com/2vs5ifl.jpg
https://stackoverflow.com/questions/6613869
复制相似问题