【问题标题】:TIF Compress CCITT4TIF 压缩 CCITT4
【发布时间】:2023-03-14 05:40:02
【问题描述】:

我正在尝试使用 CCITT4 压缩 tiff 文件。原始大小 101 KB,运行后大小减少了一点 98 KB。我的限制大小为 50 KB,我怎样才能使大小低于我的限制?代码如下

我的极限; 大小 图像宽度:1766 – 1890 像素 图片长度:915 – 1040 像素

谢谢大家。 Image Sample

public static Byte[] CompressBitmap(Bitmap img)
    {
        Bitmap bm = img;
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
        ImageCodecInfo ici = null;
        foreach (ImageCodecInfo codec in codecs)
        {
            if (codec.MimeType == "image/tiff")
                ici = codec;
        }

        EncoderParameters ep = new EncoderParameters(1);
        ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, 
                    (long)EncoderValue.Flush);
        ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 
                    (long)EncoderValue.CompressionCCITT4);
        using (var stream = new MemoryStream())
        {
            bm.Save(stream, ici, ep);
            return stream.ToArray();
        }
    }

【问题讨论】:

  • 这些是黑白图像吧?
  • 右,黑白图像,我也有尺寸限制(1766、915)
  • 源 Image PixelFormat 设置为什么?您是否尝试过 RLE 压缩?您只需要字节数组还是生成新图像?这种情况下,新Image生成后的PixelFormat是什么?
  • 另外,第 4 组生成的图像质量相当低。你确定要这个吗?您是否需要这些图像具有 TIFF 格式,或者其他格式也可以(如果您更关心压缩)?
  • 确切地说我不知道​​源图像 PixelFormat,首先我调整源图像的大小并克隆它然后运行压缩算法。最后我需要字节数组,但不要尝试 RLE 压缩,我应该用 CCITT4 压缩结果文件。我可以使用 PixelFormat 来减小尺寸吗?

标签: c# compression tiff image-compression


【解决方案1】:

由于源图像似乎是彩色图像(恰好看起来像黑白)并且它的尺寸需要调整到最大值,您需要:

  1. 按比例重新定义源图像的大小,设置转换后图像需要遵守的最大宽度和高度限制
  2. 将图像转换为1bpp Indexed 格式:Bitmap.Clone() 方法提供了定义源图像新大小和设置特定PixelFormat 的方法(PixelFormat.Format1bppIndexed,在这种情况下)。内部转换方法相当不错,生成的图像质量通常是一个很好的折衷方案。
  3. 定义quality of the Image:由于图像将被转换为黑白,其质量最初可以设置为最大值(100)。如果最终的图像字节数不符合要求,则可以重复该过程 (50KB)
  4. Compress the Image 使用 CCTII 组 4 Compression scheme
  5. Encode the Image,使用TIFF格式编码器,保存到MemoryStream做进一步处理

问题中提供的示例图像的大小(以字节为单位)在保存到文件时从最初的 94,600 字节减少到 6,786 字节以最高质量。

File.WriteAllBytes("[Image Path].tiff", imageStream.ToArray());

ConvertToBWTiffImageStream()方法可以调用为:

var maximumWidthAndHeight = new Size(1024, 768);
int quality = 100;
var compression = EncoderValue.CompressionCCITT4;
var imageStream = ConvertToBWTiffImageStream(sourceImage, maximumWidthAndHeight, quality, compression);

请注意,maximumWidthAndHeight 指定了最大宽度和最大高度,而不是图像的新尺寸(否则会失真)。图像大小根据这些值按比例缩放。


►记得添加这个:using ImageCodec = System.Drawing.Imaging.Encoder;

GetImageMaxSize()方法有点傻,我稍后会修复)

using System.Drawing;
using System.Drawing.Imaging;
using ImageCodec = System.Drawing.Imaging.Encoder;

private MemoryStream ConvertToBWTiffImageStream(Bitmap image, Size maxWidthHeight, long compressionLevel, EncoderValue compressionScheme)
{
    var imageSize = GetImageMaxSize(image, maxWidthHeight);
    var bwImage = image.Clone(new Rectangle(Point.Empty, image.Size), PixelFormat.Format1bppIndexed);
    compressionLevel = Math.Max(0, Math.Min(100, compressionLevel));

    var codecParms = new EncoderParameters(2);
    try {
        var imageCodec = ImageCodecInfo.GetImageEncoders().FirstOrDefault(enc => enc.FormatID == ImageFormat.Tiff.Guid);
        var qualityParam = new EncoderParameter(ImageCodec.Quality, compressionLevel);
        var compressionParam = new EncoderParameter(ImageCodec.Compression, (long)compressionScheme);

        var ms = new MemoryStream();
        codecParms.Param[0] = qualityParam;
        codecParms.Param[1] = compressionParam;
        image.Save(ms, imageCodec, codecParms);
        return ms;
    }
    finally {
        codecParms.Dispose();
        bwImage.Dispose();
    }
}

private Size GetImageMaxSize(Image image, Size maxSize)
{
    float scale = 1.0f;
    if (image.Width > maxSize.Width && image.Width >= image.Height) {
        scale = (float)maxSize.Width / image.Width;
    }
    else if (image.Height > maxSize.Height) {
        scale = (float)maxSize.Height / image.Height;
    }
    return new Size((int)(image.Width * scale), (int)(image.Height * scale));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2011-04-20
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多