Изменить качество изображения на лету

Я написал этот код для обрезки и изменения размера изображения на лету. Я отправляю обработанное изображение в браузер как <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>

Теперь я хочу добавить контроль качества к выходному изображению, и я нашел это Q/A. Этот ответ предлагает метод, который сохраняет изображение на диск. Я пытался приспособить это к моей цели. В настоящее время я могу только сохранить его на диске, и метод является недействительным. Я не знаю, как передать вывод своим собственным кодам перед передачей результата в браузер:

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

1 ответ

Решение

Вы можете сохранить свое растровое изображение непосредственно в MemoryStream и делать с ним все, что захотите. Ваш кодер будет применен к изображению внутри этого потока. Вместо передачи пути к файлу в качестве первого параметра метода Save просто передайте экземпляр MemoryStream. Если я правильно помню, есть также способ передать этот поток непосредственно в ответ на браузер.

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

Имейте в виду, что для sfream используйте метод statment или dispose, чтобы избежать утечки памяти.

Подробнее здесь: https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap?view=netframework-4.7.2

Другие вопросы по тегам