How can I get better results when shrinking an image

前端 未结 3 733
礼貌的吻别
礼貌的吻别 2020-12-16 19:26

I\'m scaling images down in c#, and I\'ve compared my methods with the best method in Photoshop cs5 and cannot replicate it.

In PS i\'m using bicubic sharper, which

相关标签:
3条回答
  • 2020-12-16 19:29

    Perhaps I am missing something, but I have typically used the following code below to resize/compress JPEG Images. Personally, I think the result turned out pretty well based on your source image. The code doesn't handle a few edge cases concerning input parameters, but overall gets the job done (I have additional extension methods for Cropping, and Combining image transformations if interested).

    Image Scaled to 25% original size and using 90% Compression. (~30KB output file)

    SampleImage

    Image Scaling Extension Methods:

    public static Image Resize(this Image image, Single scale)
    {
      if (image == null)
        return null;
    
      scale = Math.Max(0.0F, scale);
    
      Int32 scaledWidth = Convert.ToInt32(image.Width * scale);
      Int32 scaledHeight = Convert.ToInt32(image.Height * scale);
    
      return image.Resize(new Size(scaledWidth, scaledHeight));
    }
    
    public static Image Resize(this Image image, Size size)
    {
      if (image == null || size.IsEmpty)
        return null;
    
      var resizedImage = new Bitmap(size.Width, size.Height, image.PixelFormat);
      resizedImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
    
      using (var g = Graphics.FromImage(resizedImage))
      {
        var location = new Point(0, 0);
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.DrawImage(image, new Rectangle(location, size), new Rectangle(location, image.Size), GraphicsUnit.Pixel);
      }
    
      return resizedImage;
    }
    

    Compression Extension Method:

    public static Image Compress(this Image image, Int32 quality)
    {
      if (image == null)
        return null;
    
      quality = Math.Max(0, Math.Min(100, quality));
    
      using (var encoderParameters = new EncoderParameters(1))
      {
        var imageCodecInfo = ImageCodecInfo.GetImageEncoders().First(encoder => String.Compare(encoder.MimeType, "image/jpeg", StringComparison.OrdinalIgnoreCase) == 0);
        var memoryStream = new MemoryStream();
    
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, Convert.ToInt64(quality));
    
        image.Save(memoryStream, imageCodecInfo, encoderParameters);
    
        return Image.FromStream(memoryStream);
      }
    }
    

    Usage:

      using(var source = Image.FromFile(@"C:\~\Source.jpg"))
      using(var resized = source.Resize(0.25F))
      using(var compressed = resized.Compress(90))
        compressed.Save(@"C:\~\Output.jpg");
    

    NOTE: For anyone who may comment, you cannot dispose the MemoryStream created in the Compress method until after the image is disposed. If you reflect in to the implementation of Dispose on MemoryStream, it is actually save to not explicitly call dispose. The only alternative would be to wrap the image/memory stream in a custom implementation of a class that implements Image/IDisposable.

    0 讨论(0)
  • 2020-12-16 19:35

    I stumbled upon this question.

    I used this code to use no compression of the jpeg and it comes out like the PS version:

    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
        ImageCodecInfo ici = null; 
        foreach (ImageCodecInfo codec in codecs)
        { 
            if (codec.MimeType == "image/jpeg") 
                ici = codec; 
        } 
    
        EncoderParameters ep = new EncoderParameters(); 
        ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);
    
    0 讨论(0)
  • 2020-12-16 19:47

    Looking at the amount of JPEG artifacts, especially at the top of the image, I think you set the jpg compression to high. That results in a smaller (filesize) file, but reduces image quality and seems to add more blur.

    Can you try saving it in a higher quality? I assume the line containing CompositingQuality.HighQuality does this already, but maybe you can find an even higher quality mode. What are the differences in file size between Photoshop and C#? And how does the Photoshop image look after you saved it and reopened it? Just resizing in Photoshop doesn't introduce any jpg data loss. You will only notice that after you've saved the image as jpg and then closed and reopened it.

    0 讨论(0)
提交回复
热议问题