繁体   English   中英

保存大多数空白图像 - 文件大小,要低

[英]Saving mostly white space images - high file size, want lower

我将一些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);

但对于灰度和大部分空白的图像,是否有最佳图像格式?

看着你的图像,它是单色的,而不是灰度的。 如果单色是可以接受的,您可以使用JBIG2来压缩文档。

它对文本(以及其他内容)有特别的优化:

理想情况下,JBIG2编码器会将输入页面分割为文本区域,半色调图像区域和其他数据区域。 通常使用称为QM编码器的依赖于上下文的算术编码算法来压缩既不是文本也不是半色调的区域。 文本区域按如下方式压缩:区域中的前景像素被分组为符号。 然后,通常还使用依赖于上下文的算术编码来创建和编码符号字典,并且通过描述哪些符号出现在哪里来编码区域。

强调我的。

对于具有大块平面颜色的图像,请考虑使用PNG-8。

但是,ta.speot.ls在这种情况下的建议看起来更能满足您的需求。

我使用了一个函数,使用阈值将图像转换为黑色或白色。 这大大降低了图像尺寸,质量没有大幅降低。

    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;
        }

无损压缩将相同颜色的像素分组。 如果有100个白色像素,则存储“百个白色像素”而不是“白色像素,白色像素......”100次。

您的图像有大面积的白色。 如果你想要它压缩得很好,它必须是完全相同的白色。 所以量化你的图像。 只需减少颜色数量。

我猜你只需要它可读作为某些东西的证据,所以你不需要灰度。

最佳结果将是1位深度(2种颜色黑白),PNG和tiff给出良好的结果。

如果你可以花更多的时间在这上面,你可以做一些更多的处理,比如去除孤独的像素(噪音)。

避免使用JPEG制作照片。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM