如何在 16 位显示器上缩小原始 rgb 数据数组
Posted
技术标签:
【中文标题】如何在 16 位显示器上缩小原始 rgb 数据数组【英文标题】:How can I scale down an array of raw rgb data on a 16 bit display 【发布时间】:2009-04-10 22:19:13 【问题描述】:我在 16 位显示器上有一个原始 rgb 数据数组,尺寸为 320 * 480。数组的大小为 320*480*4 = 6144000。
我想知道如何在不损失图像质量的情况下缩小 (80 * 120)?
我找到了有关在 2D 数组中缩放图像的链接,但是如何将其应用于我的 16 位显示器数组?它不是二维数组(因为它有 16 位颜色)。
Image scaling and rotating in C/C++
谢谢。
【问题讨论】:
如果是16位颜色,为什么每个像素都是32位? 通常 32 位像素是 24 位颜色 + 8 位 alpha 或 24 位颜色 + 8 位浪费空间。 显示器好像是 16 色而不是 16 位? 【参考方案1】:如果您将大图像缩小为较小的图像,您将失去图像质量。
那么,问题是如何最小化这种损失。
有很多算法可以做到这一点,每种算法都有优点和缺点。
通常,您会对图像应用某种过滤器,例如双线性或最近邻。 Here is a discussion ImageMagick 上下文中的此类过滤器。
另外,如果输出将小于每像素 16 位,则需要执行某种形式的 Color Quantization。
【讨论】:
【参考方案2】:我假设您的意思是 16 位 rgb 显示器,而不是每种颜色(红色、绿色和蓝色)为 16 位的显示器。我还假设您知道您的 r、g 和 b 值是如何在 16 位空间中编码的,因为有 two possibilities。
因此,假设您知道如何分割色彩空间,您现在可以使用一系列字节数组来表示您的数据。变得棘手的决定是是否使用字节数组,因为您有一组算法已经可以在这些数组上完成工作,但每个字节会花费您可能无法花费的一些额外位,或者将所有内容都塞入该 16 位格式,然后对每个 16 位像素的适当位进行处理。只有你才能真正回答这个问题;如果您有内存,我会选择字节数组方法,因为它可能更快,并且您将获得一些额外的精度以使图像最终看起来更平滑(呃)。
鉴于这些假设,这个问题真的可以通过您在设备上的时间来回答。如果你有一个非常快的设备,你可以实现一个Lanczos resampling。如果您的设备速度较慢,bicubic interpolation 也可以很好地工作。如果您有更慢的设备,bilinear interpolation 是您的朋友。
如果您真的没有速度,我会在一些外部应用程序(如 Photoshop)中进行重新缩放,并保存一系列您需要时加载的位图。
【讨论】:
【参考方案3】:缩小图像的方法有很多,但没有一种方法可以保证不损失“质量”。最终,信息会在重新缩放过程中丢失。
【讨论】:
【参考方案4】:您有 16 位颜色 = 2 个字节,但在您的计算中使用了 4 个乘数。 也许您不需要减小图像大小?
一般来说,在不损失质量的情况下缩放光栅图像是不可能的。一些算法使缩放几乎没有可见的质量损失。
【讨论】:
好点。这是我得到的信息: * 原始 RGB 缓冲区的大小是 614400 * 显示器的大小是 320 * 480 * 这是一个 16 位显示器 我知道上面是正确的,因为我遵循这个 docs.blackfin.uclinux.org/doku.php?id=framebuffer 和我的结果正确显示 现在我不知道为什么缓冲区的大小是 614400。我试图从我的显示器为 320 * 480 的事实逆向工程为什么它那么大。 嗯。在您提到的文档中,它们显示了将原始数据转换为 rgb 的 perl 脚本。【参考方案5】:由于您要缩小 4 倍,因此原始图像中的每个 4x4 像素块将对应于输出图像中的单个像素。然后,您可以遍历原始图像中的每个 4x4 块,然后将其缩小为单个像素。进行这种减少的一种简单方法(也许不是最好的方法)可能是取 RGB 分量的平均值或中值。
您应该注意,您不能在不损失图像质量的情况下进行图像缩放,除非对于原始图像中的所有块,每个像素都是完全相同的颜色(这不太可能)。
【讨论】:
看起来 OP 意味着每个维度的因子为 4,因此您希望平均 4x4 块源像素,而不是 2x2,以使整体尺寸变化为 16 倍。以上是关于如何在 16 位显示器上缩小原始 rgb 数据数组的主要内容,如果未能解决你的问题,请参考以下文章