Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize image without losing quality

Hey I have this Image:

i am using this method to resize my images:

public static Bitmap ResizeImage(Image image, int width, int height)
{
    var destRect = new Rectangle(0, 0, width, height);
    var destImage = new Bitmap(width, height);

    destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

    using (var graphics = Graphics.FromImage(destImage))
    {
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        using (var wrapMode = new ImageAttributes())
        {
            wrapMode.SetWrapMode(WrapMode.TileFlipXY);
            graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
        }
    }

    return destImage;
}

However when I'm done this would be my result:

As You can see the picture is somehow dotty and poor quality. So changed my approach and used this Method to resize my picture:

public static Image ResizeImage(Image OriginalImage, Size ThumbSize)
{
    Int32 thWidth = ThumbSize.Width;
    Int32 thHeight = ThumbSize.Height;
    Image i = OriginalImage;
    Int32 w = i.Width;
    Int32 h = i.Height;
    Int32 th = thWidth;
    Int32 tw = thWidth;
    if (h > w)
    {
        Double ratio = (Double)w / (Double)h;
        th = thHeight < h ? thHeight : h;
        tw = thWidth < w ? (Int32)(ratio * thWidth) : w;
    }
    else
    {
        Double ratio = (Double)h / (Double)w;
        th = thHeight < h ? (Int32)(ratio * thHeight) : h;
        tw = thWidth < w ? thWidth : w;
    }
    Bitmap target = new Bitmap(tw, th);
    Graphics g = Graphics.FromImage(target);
    g.SmoothingMode = SmoothingMode.HighQuality;
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.InterpolationMode = InterpolationMode.High;
    Rectangle rect = new Rectangle(0, 0, tw, th);
    g.DrawImage(i, rect, 0, 0, w, h, GraphicsUnit.Pixel);
    return (Image)target;
}

But The Issue still stands. i was wondering how may i be able to resize this image to smaller size without losing quality.

I must add After resize i will create an byte array and save it within the database (Yes i know bad thing, but within this project it has to be saved within database). Also on retrieval I get the image from webapi, so that byte array will be converted to base64 string. and i show that b64 on image tag like below. e.g:

<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
    9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
like image 930
Masoud Andalibi Avatar asked Mar 08 '23 02:03

Masoud Andalibi


1 Answers

I'm using the following method for thousands of images and it never loses significant quality or results in a dotted image.

public static Image ScaleImage(Image image, int height)
{
    double ratio = (double)height/ image.Height;
    int newWidth = (int)(image.Width * ratio);
    int newHeight = (int)(image.Height * ratio);
    Bitmap newImage = new Bitmap(newWidth, newHeight);
    using (Graphics g = Graphics.FromImage(newImage))
    {
        g.DrawImage(image, 0, 0, newWidth, newHeight);
    }
    image.Dispose();
    return newImage;
}

I've taken the liberty of scaling the image you posted using this code to 128px (Like the thumbnail you posted).

Result:

enter image description here

like image 188
Koby Douek Avatar answered Mar 19 '23 22:03

Koby Douek