是否可以减少来自字节数组的图像大小

时间:2012-02-24 13:25:32

标签: c# asp.net bytearray

我有一个包含jpeg图像的字节数组。我只是想知道是否可以缩小它的尺寸?

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

4 个答案:

答案 0 :(得分:13)

请理解,没有免费午餐。通过增加压缩来减小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非常适合。

答案 1 :(得分:0)

字节数组的大小总是可以减少,但是会丢失有关图像的数据。您可以降低jpeg的质量,然后它将占用较少的数据作为字节数组。

答案 2 :(得分:0)

将JPEG字节视为大量字节的非常压缩的表示。 因此,如果您尝试应用某些函数来减少字节数,那就像尝试压缩已压缩的东西一样。

答案 3 :(得分:0)

请尝试:

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