我将一些A4图像和较小的图像保存到文件中。
我想知道什么是最好的格式。它们仅从灰度扫描中返回。然而,有些图像的尺寸非常大(与我们预期的相比)。
我们尝试将它们保存为具有不同质量的JPEG,但仍然无法将它们视为我们想要的那么小,JPEG不是最有效的格式。
A4保存质量8保存为196KB 以质量8保存的较小图像节省为28KB
因为这个图像的大部分都是空白区域,所以我们期望文件大小要小得多。文件大小比图像质量更重要。 我们做错了吗?
以下是A4图像示例
这是示例较小的图像
我们的代码是用c#编写的
// Get a bitmap.
Bitmap bmp1 = new Bitmap(@"c:\TestImageFromScanner.jpg");
ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
// Create an Encoder object based on the GUID
// for the Quality parameter category.
System.Drawing.Imaging.Encoder myEncoder =
System.Drawing.Imaging.Encoder.Quality;
// Create an EncoderParameters object.
// An EncoderParameters object has an array of EncoderParameter
// objects. In this case, there is only one
// EncoderParameter object in the array.
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,8L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(@"c:\TestJpegQuality8.jpg", jgpEncoder, myEncoderParameters);
答案 0 :(得分:6)
但灰度和大部分空白的图像是否有最佳图像格式?
看着你的图像,它是单色的,而不是灰度的。如果单色可以接受,您可以使用JBIG2压缩文档。
它对文本(以及其他内容)有特别的优化:
理想情况下,JBIG2编码器会将输入页面分割为文本区域,半色调图像区域和其他数据区域。通常使用称为QM编码器的依赖于上下文的算术编码算法来压缩既不是文本也不是半色调的区域。文本区域按如下方式压缩:区域中的前景像素被分组为符号。 然后创建和编码符号字典,通常也使用依赖于上下文的算术编码,并通过描述哪些符号出现在哪里来编码区域。
强调我的。
答案 1 :(得分:1)
对于具有大块平面颜色的图像,请考虑使用PNG-8。
但是,ta.speot.ls在这种情况下的建议看起来更能满足您的需求。
答案 2 :(得分:1)
我使用了一个函数,使用阈值将图像转换为黑色或白色。这大大降低了图像尺寸,质量没有大幅降低。
var downsizeImage = ImageTools.ConvertToBitonal(scaledBmp, 500);
downsizeImage.Save(string.Format(@"C:\Temp\{0}Downsized.png", betSlipImage.BetSlipID), ImageFormat.Png);
var ms = new MemoryStream();
downsizeImage.Save(ms, ImageFormat.Png);
public static Bitmap ConvertToBitonal(Bitmap original, int threshold)
{
Bitmap source;
// If original bitmap is not already in 32 BPP, ARGB format, then convert
if (original.PixelFormat != PixelFormat.Format32bppArgb)
{
source = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
source.SetResolution(original.HorizontalResolution, original.VerticalResolution);
using (var g = Graphics.FromImage(source))
{
g.DrawImageUnscaled(original, 0, 0);
}
}
else
{
source = original;
}
// Lock source bitmap in memory
var sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Copy image data to binary array
var imageSize = sourceData.Stride * sourceData.Height;
var sourceBuffer = new byte[imageSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);
// Unlock source bitmap
source.UnlockBits(sourceData);
// Create destination bitmap
var destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed);
destination.SetResolution(original.HorizontalResolution, original.VerticalResolution);
// Lock destination bitmap in memory
var destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
// Create destination buffer
imageSize = destinationData.Stride * destinationData.Height;
var destinationBuffer = new byte[imageSize];
var sourceIndex = 0;
var destinationIndex = 0;
var pixelTotal = 0;
byte destinationValue = 0;
var pixelValue = 128;
var height = source.Height;
var width = source.Width;
// Iterate lines
for (var y = 0; y < height; y++)
{
sourceIndex = y * sourceData.Stride;
destinationIndex = y * destinationData.Stride;
destinationValue = 0;
pixelValue = 128;
// Iterate pixels
for (var x = 0; x < width; x++)
{
// Compute pixel brightness (i.e. total of Red, Green, and Blue values) - Thanks murx
// B G R
pixelTotal = sourceBuffer[sourceIndex] + sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2];
if (pixelTotal > threshold)
{
destinationValue += (byte)pixelValue;
}
if (pixelValue == 1)
{
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = 0;
pixelValue = 128;
}
else
{
pixelValue >>= 1;
}
sourceIndex += 4;
}
if (pixelValue != 128)
{
destinationBuffer[destinationIndex] = destinationValue;
}
}
// Copy binary image data to destination bitmap
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);
// Unlock destination bitmap
destination.UnlockBits(destinationData);
// Dispose of source if not originally supplied bitmap
if (source != original)
{
source.Dispose();
}
// Return
return destination;
}
答案 3 :(得分:0)
无损压缩将相同颜色的像素分组。如果有100个白色像素,则存储“百个白色像素”而不是“白色像素,白色像素......”100次。
您的图像有大面积的白色。如果你想要它压缩得很好,它必须是完全相同的白色。所以量化你的图像。只需减少颜色数量。
我想你只需要它可以作为某些东西的证据,所以你不需要灰度。
最佳效果是1位深度(2种颜色黑白),PNG和tiff效果很好。
如果你可以花更多的时间在这上面,你可以做更多的处理,比如去除孤独的像素(噪音)。
避免使用JPEG制作照片。