TIF Compress CCITT4 - PullRequest
       116

TIF Compress CCITT4

1 голос
/ 25 марта 2020

Я пытаюсь сжать TIFF-файл с помощью CCITT4. Оригинальный размер 101 КБ, после запуска уменьшите размер до 98 КБ. Мой лимит размером 50 КБ, как я могу сделать размер ниже моего лимита? код ниже

Мои ограничения; Размер <50 КБ <br>Ширина изображения: 1766 - 1890 пикселей Длина изображения: 915 - 1040 пикселей

Спасибо всем. Образец изображения

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

1 Ответ

0 голосов
/ 25 марта 2020

Поскольку исходное изображение выглядит как цветное изображение (которое выглядит как черно-белое) и его размеры необходимо отрегулировать до максимального значения, необходимо:

  1. Пропорционально переопределить Размер исходного изображения, установка максимальных пределов ширины и высоты, которые должны соблюдаться преобразованным изображением
  2. Преобразование изображения в формат 1bpp Indexed: метод Bitmap.Clone () обеспечивает означает как определить исходный размер изображения, так и задать новый размер c PixelFormat (в данном случае PixelFormat.Format1bppIndexed). Метод внутреннего преобразования довольно хорош, качество получаемого изображения обычно является хорошим компромиссом.
  3. Определите качество изображения : поскольку изображение будет преобразовано в черно-белое, его качество может быть изначально установлено на максимум (100). Процесс может быть повторен, если окончательное число байтов изображения не соответствует требованиям (50KB)
  4. Сжать изображение , используя CCTII Group 4 Схема сжатия
  5. Кодировать изображение , используя кодировщик формата 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));
}
...