Можно ли уменьшить размер изображения из байтового массива? - PullRequest
5 голосов
/ 24 февраля 2012

У меня есть байтовый массив, содержащий изображение в формате JPEG.Мне просто интересно, можно ли уменьшить его размер?

Правка: ОК.Я признал свою ошибку.Тогда мой вопрос, как я могу снизить качество изображения, получаемого из байтового массива.

Ответы [ 4 ]

13 голосов
/ 24 февраля 2012

Пожалуйста, поймите, что нет бесплатного обеда. Уменьшение размера изображения JPEG за счет увеличения сжатия также приведет к снижению качества изображения. Тем не менее, вы можете уменьшить размер изображения JPEG, используя класс Image. Этот код предполагает, что inputBytes содержит исходное изображение.

var jpegQuality = 50; 
Image image; 
using (var inputStream = new MemoryStream(inputBytes)) {
  image = Image.FromStream(inputStream);
  var jpegEncoder = ImageCodecInfo.GetImageDecoders() 
    .First(c => c.FormatID == ImageFormat.Jpeg.Guid); 
  var encoderParameters = new EncoderParameters(1); 
  encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, jpegQuality); 
  Byte[] outputBytes; 
  using (var outputStream = new MemoryStream()) { 
    image.Save(outputStream, jpegEncoder, encoderParameters);
    outputBytes = outputStream.ToArray(); 
  } 
}

Теперь outputBytes содержит повторно сжатую версию изображения с использованием другого качества JPEG.

Уменьшая jpegQuality (должно быть в диапазоне 0-100), вы можете увеличить сжатие за счет более низкого качества изображения. Подробнее см. В поле Encoder.Quality.

Вот пример, где вы можете увидеть, как jpegQuality влияет на качество изображения. Это та же фотография, сжатая с использованием 20, 50 и 80, как значение jpegQuality. Размеры: 4,99, 8,28 и 12,9 КБ.

JPEG quality sample image

Обратите внимание, что текст становится «нечетким» даже при высоком качестве. Вот почему вы должны избегать использования JPEG для изображений с однородно окрашенными областями (изображения / диаграммы / диаграммы, созданные на компьютере). Вместо этого используйте PNG. Для фотографий JPEG очень подходит, если вы не слишком снизите качество.

0 голосов
/ 08 ноября 2018

Пожалуйста, попробуйте:

// Create a thumbnail in byte array format from the image encoded in the passed byte array.  
// (RESIZE an image in a byte[] variable.)  
public static byte[] CreateThumbnail(byte[] PassedImage, int LargestSide)  
{  
    byte[] ReturnedThumbnail;  

    using (MemoryStream StartMemoryStream = new MemoryStream(),  
                        NewMemoryStream = new MemoryStream())  
    {  
        // write the string to the stream  
        StartMemoryStream.Write(PassedImage, 0, PassedImage.Length);  

        // create the start Bitmap from the MemoryStream that contains the image  
        Bitmap startBitmap = new Bitmap(StartMemoryStream);  

        // set thumbnail height and width proportional to the original image.  
        int newHeight;  
        int newWidth;  
        double HW_ratio;  
        if (startBitmap.Height > startBitmap.Width)  
        {  
            newHeight = LargestSide;  
            HW_ratio = (double)((double)LargestSide / (double)startBitmap.Height);  
            newWidth = (int)(HW_ratio * (double)startBitmap.Width);  
        }  
        else 
        {  
            newWidth = LargestSide;  
            HW_ratio = (double)((double)LargestSide / (double)startBitmap.Width);  
            newHeight = (int)(HW_ratio * (double)startBitmap.Height);  
        }  

        // create a new Bitmap with dimensions for the thumbnail.  
        Bitmap newBitmap = new Bitmap(newWidth, newHeight);  

        // Copy the image from the START Bitmap into the NEW Bitmap.  
        // This will create a thumnail size of the same image.  
        newBitmap = ResizeImage(startBitmap, newWidth, newHeight);  

        // Save this image to the specified stream in the specified format.  
        newBitmap.Save(NewMemoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);  

        // Fill the byte[] for the thumbnail from the new MemoryStream.  
        ReturnedThumbnail = NewMemoryStream.ToArray();  
    }  

    // return the resized image as a string of bytes.  
    return ReturnedThumbnail;  
}  

// Resize a Bitmap  
private static Bitmap ResizeImage(Bitmap image, int width, int height)  
{  
    Bitmap resizedImage = new Bitmap(width, height);  
    using (Graphics gfx = Graphics.FromImage(resizedImage))  
    {  
        gfx.DrawImage(image, new Rectangle(0, 0, width, height),   
            new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);  
    }  
    return resizedImage;  
}
0 голосов
/ 24 февраля 2012

Представьте, что байты JPEG являются очень сжатым представлением гораздо большего количества байтов. Поэтому, если вы попытаетесь применить некоторую функцию для уменьшения количества байтов, это все равно, что пытаться сжать уже сжатую вещь.

0 голосов
/ 24 февраля 2012

Размер байтового массива всегда можно уменьшить, но вы потеряете данные о вашем изображении.Вы можете снизить качество JPEG, тогда он будет занимать меньше данных в виде байтового массива.

...