简体   繁体   中英

Change image quality on the fly

I have write this code to do crop and resize the image on the fly . I send the processed image to the browser like <img src="imagehandler.aspx?img=1.jpg"> :

imagehandler.aspx:

<%@ Page Language="C#"%>
<%@ import Namespace="System.Drawing" %>
<%@ import Namespace="System.IO" %>
<script runat="server">
    System.Drawing.Image oldImage, newImage,cloned,tempImage;
    void Page_Load(Object sender, EventArgs e) {
    string strFileName = Convert.ToString(Request.QueryString["img"]);
    oldImage = System.Drawing.Image.FromFile(Server.MapPath(strFileName));
    rect= new Rectangle(0,50,100,100);  
    cloned = new Bitmap(oldImage ).Clone(rect, tempImage.PixelFormat);
    newImage = new Bitmap(cloned);
    cloned.Dispose();   

    Response.ContentType = "image/jpeg";
    newImage.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
    oldImage.Dispose();
    newImage.Dispose();
    oldImage = null;
    newImage = null;
    }
</script>

Now I want to add quality control to the output image and I found this Q/A This answer suggests a method which saves the image to the disk. I have tried to fit it to my purpose. Currently I can only save it on the disk and the method is void. I don't know how to pass the output to my own codes before streaming the result to the browser:

private void VaryQualityLevel(bmp1)
{
    ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
    System.Drawing.Imaging.Encoder myEncoder= System.Drawing.Imaging.Encoder.Quality;
    EncoderParameters myEncoderParameters = new EncoderParameters(1);
    EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
    myEncoderParameters.Param[0] = myEncoderParameter;
    bmp1.Save(@"c:\TestPhotoQualityFifty.jpg", jgpEncoder,myEncoderParameters);
}

private ImageCodecInfo GetEncoder(ImageFormat format)
{
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
    foreach (ImageCodecInfo codec in codecs)
    {
        if (codec.FormatID == format.Guid)
        {
            return codec;
        }
    }
    return null;
}

You can save your bitmap directly to MemoryStream and do whatever you want with it. Your encoder will be applied to image inside this stream. Instead of passing file path as first parameter of Save method just pass instance of MemoryStream. If I remember correctly there's also a way to pass this stream directly as a response to browser.

using(var ms = new MemoryStream()) 
{
    bmp1.Save(ms, jgpEncoder, myEncoderParameters);
    var bmp2 = new BitMap(ms);
    //do whatever you want with this image
}

Keep in mind to use using statment or dispose method for sfream to avoid memory leak.

More details here: https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap?view=netframework-4.7.2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM