Вопрос по c#, jpeg, memorystream, image – Сохранение в формате JPEG из потока памяти в C #

3

У меня есть метод, как показано ниже, чтобы сохранить изображение в формате JPEG. Я хочу сохранить все картинки с одинаковой высотой и шириной без искажений.

Как я могу это сделать? Пожалуйста помоги

public void SaveFileOnDisk(MemoryStream ms, string FileName)
{
    try
    {
        string appPath = HttpContext.Current.Request.ApplicationPath;
        string physicalPath = HttpContext.Current.Request.MapPath(appPath);
        string strpath = physicalPath + "\\Images";
        string WorkingDirectory = strpath;


        System.Drawing.Image imgSave = System.Drawing.Image.FromStream(ms);
        Bitmap bmSave = new Bitmap(imgSave);
        Bitmap bmTemp = new Bitmap(bmSave);

        Graphics grSave = Graphics.FromImage(bmTemp);
        grSave.DrawImage(imgSave, 0, 0, imgSave.Width, imgSave.Height);

        bmTemp.Save(WorkingDirectory + "\\" + FileName + ".jpg");


        imgSave.Dispose();
        bmSave.Dispose();
        bmTemp.Dispose();
        grSave.Dispose();
    }
    catch (Exception ex)
    {
        //lblMsg.Text = "Please try again later.";
    }

}
Можете ли вы объяснить, что вы имеете в виду под «одинаковой высотой и шириной, без искажений»? Если исходные фотографии имеют другое соотношение сторон (т.е. соотношение ширины к высоте), чем ваши выходные размеры, выwill есть искажение. Единственными вариантами, позволяющими избежать искажения, являются (1) почтовый ящик с рамкой на одной стороне или другой или (2) размер целевого объекта, равный одному «фиксированному»; размер и одно измерение, которое изменяется в зависимости от формата изображения исходной фотографии. richardtallent
Это действительно не возможно сейчас, не так ли? Если вы получите изображение размером 400 x 300 и еще одно изображение размером 400 x 100, то вы не сможете сохранить их с тем же размером без искажений.something, Вы можете использовать почтовые ящики, которые вам не подходят, использовать Graphics.DrawImage (). Hans Passant
@acadia, почему вы не принимаете ответ techno

Ваш Ответ

2   ответа
1

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

public Image ResizeWithSameRatio(Image image, float width, float height)
{
    // the colour for letter boxing, can be a parameter
    var brush = new SolidBrush(Color.Black);

    // target scaling factor
    float scale = Math.Min(width / image.Width, height / image.Height);

    // target image
    var bmp = new Bitmap((int)width, (int)height);
    var graph = Graphics.FromImage(bmp);

    var scaleWidth = (int)(image.Width * scale);
    var scaleHeight = (int)(image.Height * scale);

    // fill the background and then draw the image in the 'centre'
    graph.FillRectangle(brush, new RectangleF(0, 0, width, height));
    graph.DrawImage(image, new Rectangle(((int)width - scaleWidth)/2, ((int)height - scaleHeight)/2, scaleWidth, scaleHeight));

    return bmp;
}

Теперь ваша функция использования может быть значительно упрощена (при условии целевых изображений 1024x768 здесь):

public void SaveFileOnDisk(MemoryStream ms, string FileName)
{
    try
    {
        string appPath = HttpContext.Current.Request.ApplicationPath;
        string physicalPath = HttpContext.Current.Request.MapPath(appPath);
        string strpath = physicalPath + "\\Images";
        string WorkingDirectory = strpath;

        using (var original = Image.FromStream(ms))
        using (var resized = ResizeWithSameRatio(original, 1024, 768))
        {
            resized.Save(WorkingDirectory + "\\" + FileName + ".jpg");
        }
    }
    catch (Exception ex)
    {
        //lblMsg.Text = "Please try again later.";
    }
}

Обратите внимание на добавленное упрощение с точки зрения количества переменных и их размещения с использованиемusing вместоDispose().

3

Private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
    double srcWidth = img.Source.Width;
    double srcHeight = img.Source.Height;

    double resizeWidth = srcWidth;
    double resizeHeight = srcHeight;

    double aspect = resizeWidth / resizeHeight;

    if (resizeWidth > maxWidth)
    {
        resizeWidth = maxWidth;
        resizeHeight = resizeWidth / aspect;
    }
    if (resizeHeight > maxHeight)
    {
        aspect = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth = resizeHeight * aspect;
    }

    img.Width = resizeWidth;
    img.Height = resizeHeight;
}

Вы можете использовать этот код, чтобы изменить размер изображения до нужного размера перед сохранением

Похожие вопросы