我一直在使用
FJCore
一个Silverlight项目中的库来帮助进行一些实时的图像处理,我正在尝试找出如何从库中获得更多的压缩和性能。现在,据我了解,jpeg标准允许您指定色度次采样率(请参见
http://en.wikipedia.org/wiki/Chroma_subsampling
和
http://en.wikipedia.org/wiki/Jpeg
)
出现
这应该使用hsampfactor和vsampfactor数组在fjcore库中实现:
public static readonly byte[] HsampFactor = { 1, 1, 1 };
public static readonly byte[] VsampFactor = { 1, 1, 1 };
然而,我很难弄清楚如何使用它们。在我看来,当前值应该表示4:4:4次采样(例如,完全没有次采样),如果我想得到4:1:1次采样,正确的值应该是这样的:
public static readonly byte[] HsampFactor = { 2, 1, 1 };
public static readonly byte[] VsampFactor = { 2, 1, 1 };
至少,这是其他类似库使用这些值的方式(例如,请参见示例代码
here
对于LBJPEG)。
但是,上述2、1、1的值以及我尝试过的任何其他值集,除了1、1、1都不会产生清晰的图像。在查看代码时,它看起来也不像是这样写的。但在我的生活中,我不知道fjcore代码实际上是什么
尝试
去做。似乎它只是使用样本因子来重复已经完成的操作——也就是说,如果我不知道更好的话,我会说这是一个bug。但这是一个完全建立的库,基于一些相当成熟的Java代码,所以如果是这样的话,我会感到惊讶。
对于如何使用这些值获得4:2:2或4:1:1色度子采样,有人有什么建议吗?
值得一提的是,这是
JpegEncoder
班级:
for (comp = 0; comp < _input.Image.ComponentCount; comp++)
{
Width = _input.BlockWidth[comp];
Height = _input.BlockHeight[comp];
inputArray = _input.Image.Raster[comp];
for (i = 0; i < _input.VsampFactor[comp]; i++)
{
for (j = 0; j < _input.HsampFactor[comp]; j++)
{
xblockoffset = j * 8;
yblockoffset = i * 8;
for (a = 0; a < 8; a++)
{
int y = ypos + yblockoffset + a; if (y >= _height) break;
for (b = 0; b < 8; b++)
{
int x = xpos + xblockoffset + b; if (x >= _width) break;
dctArray1[a, b] = inputArray[x, y];
}
}
dctArray2 = _dct.FastFDCT(dctArray1);
dctArray3 = _dct.QuantizeBlock(dctArray2, FrameDefaults.QtableNumber[comp]);
_huf.HuffmanBlockEncoder(buffer, dctArray3, lastDCvalue[comp], FrameDefaults.DCtableNumber[comp], FrameDefaults.ACtableNumber[comp]);
lastDCvalue[comp] = dctArray3[0];
}
}
}
注意,在I&J循环中,它们不控制任何类型的像素跳跃:如果hsampfactor[0]设置为2,则它只捕获两个块而不是一个块。