从字节数组中获取的图像是否可以缩小尺寸?

6

我有一个包含JPEG图像的字节数组。我想知道是否可以减小它的大小?

编辑:好的,我承认我的错误。那么我的问题是如何减少来自字节数组的图像的质量。


3
什么意思?一旦创建,数组大小就固定不变,但是您是在谈论图像压缩吗?减少质量?减小图像尺寸?请澄清。 - Jon Skeet
像披萨一样切片并食用。抱歉,字节数组让我想起了披萨。特别是循环缓冲区。 - mauris
4个回答

20
请理解,没有免费的午餐。通过增加压缩来减小JPEG图像的大小也会降低图像的质量。然而,你可以使用Image类来缩小JPEG图像的大小。此代码假定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 KB。

JPEG quality sample image

注意,即使质量很高,文本也会变得“模糊”。这就是为什么应该避免在具有均匀着色区域的图像(在计算机上创建的图像/图表/图解)中使用JPEG。改用PNG。对于照片,如果不将质量降低太多,JPEG非常合适。

GDI+ 发生了一般性错误。:(在这行代码中:image.Save(memoryStream, jpegEncoder, encoderParameters); - Cute Bear
@MehmetBudak:抱歉,代码已修复。(Image类是“惰性”的,并尽可能晚地访问图像字节。之前,我过早地处理了输入缓冲区。) - Martin Liversage

3

请尝试以下方法:

// 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

字节数组的大小总是可以减小的,但您将会失去有关图像的数据。您可以降低JPEG的质量,这样它作为字节数组所占用的数据就会更少。


0

将JPEG字节想象成是对大量字节进行非常压缩的表示。

因此,如果您尝试应用某些函数来减少字节数,就像尝试压缩已经被压缩过的东西一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接