После изменения размера белое изображение становится серым - PullRequest
5 голосов
/ 25 июля 2011

Я искал в Google какое-то решение и нашел, я пытался реализовать его в своем коде, но оно не работает. Проблема в том, что после изменения размера белых изображений они получают серую рамку.

Вот ссылка на решение, которое я нашел:

Там написано: Эта проблема возникает, потому что вы интерполируете данные изображения в новый размер, но по краям нет пикселей для интерполяции и .NET использует черные пиксели для этих краев по умолчанию. Чтобы это исправить, вам нужно использовать Класс ImageAttributes в вашем вызове DrawImage ....

https://groups.google.com/group/microsoft.public.dotnet.framework.drawing/browse_thread/thread/d834851b49274fd9/81a4fd43694457ac?hl=en&lnk=st&q=DrawImage+resized+border#81a4fd43694457ac

КОД 1: И это мой код С РЕАЛИЗАЦИЕЙ ImageAttributes:

Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()

    Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))

        Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)

        Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)

            Using canvas As Graphics = Graphics.FromImage(newImage)

                Using ia As New ImageAttributes

                    ia.SetWrapMode(Drawing2D.WrapMode.TileFlipXY)
                    canvas.SmoothingMode = SmoothingMode.AntiAlias
                    canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
                    canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
                    canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)

                    Dim m As New MemoryStream()

                    newImage.Save(m, ImageFormat.Png)
                    Return m.GetBuffer()

                End Using

            End Using

        End Using

    End Using

End Function

Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size

    Dim newSize As New Size()

    If oldSize.Height > oldSize.Width Then

        newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
        newSize.Height = targetSize

    Else

        newSize.Width = targetSize
        newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))

    End If

    Return newSize

End Function

КОД 2: КОД, КОТОРЫЙ ПРЕДОСТАВЛЯЕТ СЕРЫЙ ГРАНИЦУ НА БЕЛОМ ИЗОБРАЖЕНИИ

Вот изображение после изменения размера:

enter image description here

новый размер изображения по ширине = 400px

Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()

    Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))

        Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)

        Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)

            Using canvas As Graphics = Graphics.FromImage(newImage)

                    canvas.SmoothingMode = SmoothingMode.AntiAlias
                    canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
                    canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
                    canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize))

                    Dim m As New MemoryStream()

                    newImage.Save(m, ImageFormat.Png)
                    Return m.GetBuffer()

            End Using

        End Using

    End Using

End Function

Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size

    Dim newSize As New Size()

    If oldSize.Height > oldSize.Width Then

        newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
        newSize.Height = targetSize

    Else

        newSize.Width = targetSize
        newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))

    End If

    Return newSize

End Function

ОБНОВЛЕНИЕ 30.07.2011 .:

CODE 1 решил проблему с серыми полями на белых изображениях, но есть новая проблема . Проблема в этой строке кода:

canvas.DrawImage (oldImage, New Rectangle (Новая точка (0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)

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

Например:

Если я хочу выгрузить, измените размер и сохраните исходное изображение, например 640x480px, для которого targetSize составляет 400px. В качестве вывода я получаю изображение шириной 400px, высотой 300px, без серых границ, но oldImage не изменяется и не масштабируется до 400px. Установлено, что oldImage рисуется с оригинальным разрешением. Как масштабировать oldImage, чтобы рисовать правильно? Может кто-нибудь указать мне правильное решение или изменить код?

Спасибо всем, но я нашел решение всех своих проблем.

КОД 1 работал некорректно из-за следующей строки кода:

canvas.DrawImage (oldImage, New Rectangle (Новая точка (0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)

РЕШЕНИЕ:

canvas.DrawImage (oldImage, New Rectangle (Новая точка (0, 0), newSize), 0, 0, oldImage.Width , oldImage.Height , GraphicsUnit.Pixel а)

ЗДЕСЬ ПОЛНЫЙ РАБОЧИЙ КОД (измененное изображение без серых / черных полей):

Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()

    Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))

        Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)

        Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)

            Using canvas As Graphics = Graphics.FromImage(newImage)

                Using ia As New ImageAttributes

                    ia.SetWrapMode(Drawing2D.WrapMode.TileFlipXY)
                    canvas.SmoothingMode = SmoothingMode.AntiAlias
                    canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
                    canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
                    canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, oldImage.Width, oldImage.Height, GraphicsUnit.Pixel, ia)

                    Dim m As New MemoryStream()

                    newImage.Save(m, ImageFormat.Png)
                    Return m.GetBuffer()

                End Using

            End Using

        End Using

    End Using

End Function

Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size

    Dim newSize As New Size()

    If oldSize.Height > oldSize.Width Then

        newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
        newSize.Height = targetSize

    Else

        newSize.Width = targetSize
        newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))

    End If

    Return newSize

End Function

1 Ответ

1 голос
/ 02 сентября 2011

Вот функция из моего класса, вам придется заменить некоторые свойства класса (ThumbNailSize.Width, ThumbNailSize.Height):

public void ResizeImage(HttpPostedFile fil, string sPhysicalPath, 
                              string sOrgFileName,string sThumbNailFileName,
                              ImageFormat oFormat, int rez)
{

    try
    {

        System.Drawing.Image oImg = System.Drawing.Image.FromStream(fil.InputStream);

        decimal pixtosubstract = 0;
        decimal percentage;

        //default
        Size ThumbNailSizeToUse = new Size();
        if (ThumbNailSize.Width < oImg.Size.Width || ThumbNailSize.Height < oImg.Size.Height)
        {
            if (oImg.Size.Width > oImg.Size.Height)
            {
                percentage = (((decimal)oImg.Size.Width - (decimal)ThumbNailSize.Width) / (decimal)oImg.Size.Width);
                pixtosubstract = percentage * oImg.Size.Height;
                ThumbNailSizeToUse.Width = ThumbNailSize.Width;
                ThumbNailSizeToUse.Height = oImg.Size.Height - (int)pixtosubstract;
            }
            else
            {
                percentage = (((decimal)oImg.Size.Height - (decimal)ThumbNailSize.Height) / (decimal)oImg.Size.Height);
                pixtosubstract = percentage * (decimal)oImg.Size.Width;
                ThumbNailSizeToUse.Height = ThumbNailSize.Height;
                ThumbNailSizeToUse.Width = oImg.Size.Width - (int)pixtosubstract;
            }

        }
        else
        {
            ThumbNailSizeToUse.Width = oImg.Size.Width;
            ThumbNailSizeToUse.Height = oImg.Size.Height;
        }

        Bitmap bmp = new Bitmap(ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);
        bmp.SetResolution(rez, rez);
        System.Drawing.Image oThumbNail = bmp;

        bmp = null;

        Graphics oGraphic = Graphics.FromImage(oThumbNail);

        oGraphic.CompositingQuality = CompositingQuality.HighQuality;

        oGraphic.SmoothingMode = SmoothingMode.HighQuality;

        oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;

        Rectangle oRectangle = new Rectangle(0, 0, ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);

        oGraphic.DrawImage(oImg, oRectangle);

        oThumbNail.Save(sPhysicalPath  + sThumbNailFileName, oFormat);

        oImg.Dispose();

    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
    }

}
...