views:

83

answers:

1

Hello,

I have got a problem when trying to scale an image. The problem presents itself when the image i am trying to scale (original) is smaller than the size i am trying to scale up to.

For example, an image with the width of 850px and the height of 700px trying to be scaled up to 950px width and height. The image seems to be scaled properly but is beeing drawn wrong on my bitmap. The code to scale the image will follow. The width beeing sent into ScaleToFitInside is the width and height trying to scale to, 950px both in my example.

 public static Image ScaleToFitInside(Image image, int width, int height) {
                Image reszied = ScaleToFit(image, width, height);

            Bitmap bitmap = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(bitmap)) {
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                Rectangle rect = new Rectangle(0, 0, width, height);
                g.FillRectangle(Brushes.White, rect);

                int x = (int)(((float)width - (float)reszied.Width) / 2);
                int y = (int)(((float)height - (float)reszied.Height) / 2);
                Point p = new Point(x, y);
                g.DrawImageUnscaled(reszied, p);

                foreach (PropertyItem item in image.PropertyItems) {
                    bitmap.SetPropertyItem(item);
                }
            }

            return bitmap;
        }

            public static Image ScaleToFit(Image image, int maxWidth, int maxHeight) {
            int width = image.Width;
            int height = image.Height;
            float scale = Math.Min(
                ((float)maxWidth / (float)width),
                ((float)maxHeight / (float)height));

            return (scale < 1) ? Resize(image, (int)(width * scale), (int)(height * scale)) : image;
        }

public static Image Resize(Image image, int width, int height) {
            Bitmap bitmap = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(bitmap)) {
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                Rectangle rect = new Rectangle(0, 0, width, height);
                g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);

                foreach (PropertyItem item in image.PropertyItems) {
                    bitmap.SetPropertyItem(item);
                }
            }
            return bitmap;
        }

So the picture gets scaled, but beeing drawn wrong on my bitmap causing the image to "fall" outside of my bitmap and not presenting its whole self.

Example: When sending in the values 2000x2000 (trying to upscale). The following happens.

Since the original picture is smaller than the upsizing values i do not want to "sacle it up", but to remain the same size. The effect i want is do draw a rectangle with the size of 2000x2000 and draw the image in the center of it.

My example picture produces these values:

width = 2000; height = 2000; resized.Width will be 1000 and resized.Height will be 737 (original pictures size).

x = (2000 - 1000) / 2 = 500; y = (2000 - 737) / 2 = 631.

When drawing these values onto a paper and matching it to the rectangle it seems to be the right values, but the image is still drawn on th wrong spot, not in the middle at all.

Thanks in advance.

A: 

You do realize the following 2 variables will be negative when you 'upsize'?

int x = (int)(((float)width - (float)reszied.Width) / 2);
int y = (int)(((float)height - (float)reszied.Height) / 2);
leppie
hmms, that can't be right. When i log out the variables in the eventlog i get the following result. Original image 640x480. Image trying to scale up to 1250x1300, then x = 305 and y = 410 so no negative values here.
Then I am not sure what values you are passing: `(480 - 1300)/2 < 0`
leppie
In my test picture i send in a picture width the width of 640 and the height of 480. If the picture in smaller then the upsizing measures the picture will remain the same size. Your are putting the values in the wrong order. The first variable is the value trying to upzise or downsize to beeing sent from the webservice. The resized.Height is the pictures height, also in this case the resized picture will remain the same size. Therefore it will be (1250 - 640) / 2 and (1300 - 480).
It must to have something to do with the DrawImage() method. Bug som something? Because all the values are rightly calculated but the picture is drawn on the wrong place.
I found a solution to the problem. It seems to be DrawImageUnscaled method that does downscales the picture. Using this method fixed the problem: g.DrawImage(reszied, new Rectangle(x, y, reszied.Width, reszied.Height), new Rectangle(0, 0, reszied.Width, reszied.Height), GraphicsUnit.Pixel);