How to increase image's height and width without stretching it - c#

I have a div section of width 1000px and 290 px height.if i upload image of width 500px and height 400px,and increase height and width from code,here is my code sample,it get stretch the image
var thumbnailImg = new Bitmap(newWidth, newHeight);
var thumbGraph = Graphics.FromImage(thumbnailImg);
thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
//Bitmap bmpImage = new Bitmap(img);
var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
//Bitmap bmpcrop = bmpImage.Clone(imageRectangle, bmpImage.PixelFormat);
//return (Image)bmpcrop;
thumbGraph.DrawImage(img, imageRectangle);
MemoryStream stram = new MemoryStream();
thumbnailImg.Save(stram, img.RawFormat);
byte[] imagebytes = stram.ToArray();
return imagebytes;

To resize an image ensuring that it is the same proportions, the ratio of the initial height x width (h x w) will have to be the same as the final h x w.
In your case your initial ratio is 500:400 while the final is 1000:290.
From 500:400, you can make it 1000:800, making it 2x bigger. Here the initial ratio is the same as the final ratio.
However, this won't fit the width of your specified div.
The other way is to reduce the width to 290, which means to proportionally reduce the height, you have to make the height be reduced by a factor of (1000 * (290/400)) which will be less than 1000.
So the only way is to either change your initial picture dimensions or your div dimensions if you want a perfect fit.

Related

ASP.NET uploading image with Resizing turn out that Image flip over when image is over 1MB

I have been uploading image using asp.net image upload control and turns out that when i upload image whose size is over 1MB it flip over i.e it rotates 90 degree automatically but not for the case when size is below 1MB. Here is the code that I have used until now.
string path = "ImagePath goes here";
string fileName = image.jpg;
fileupload.SaveAs(path + fileName); //here the original size image is saved
Stream strm = fileupload.PostedFile.InputStream;
double scaleFactor = 0.5;
var image = Image.FromStream(strm);
var newWidth = (int)(image.Width * scaleFactor);
var newHeight = (int)(image.Height * scaleFactor);
var thumbnailImg = new Bitmap(newWidth, newHeight);
var thumbGraph = Graphics.FromImage(thumbnailImg);
thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
thumbGraph.DrawImage(image, imageRectangle);
thumbnailImg.Save(path + fileName, image.RawFormat); //After saving this I get the resized image but image flipover 90 degree
This is the code that I have done until now. Please help me guys to overcome this issue.

size of bitmap in drawImage

I've asked question on proper scaling without rim on right and bottom. link
I've checked and size of bitmap is 32 by 32 pixels.
When i try to draw it on pictureBox with drawImage(Image, int, int) it draws it little bit bigger than size of bitmap like 36 by 36 or 40 by 40. Not sure.
But when i add width and height to drawImage it draws it 32 by 32. Is this supposed to happend.
Edit:
internal void draw(Graphics g, int x, int y)
{
int s = Game.scale;
Bitmap resized = (s > 1) ? ResizeImage(image, width*s, height*s) : image;
g.DrawImage(resized, x * width * s, y * height * s);
}
private 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;
}
Feature, not a bug. If you don't specify the target size then DrawImage() pays attention to the physical size of the image. The size it had when it was created, in inches. Something you can see back in the debugger, look at the bitmap's HorizontalResolution and VerticalResolution properties.
With the diagnostic that it is probably 120 dots-per-inch, programmers commonly run their video adapter at 125% today. So the drawn image becomes 1.25 * 32 = 40 pixels.
Keep in mind that this kind of rescaling tends to be important, such an image can easily turn into but a fleck of dust on an upscale 4K monitor. They are getting pretty affordable today. Whether you want this or not depends on how the rest of your UI rescales. Check out this post about dpiAwareness in a Winforms app.

C# - Decrease image resolution increases file size

I have an MVC application where you can upload a picture and it gets resized to max. 50KB.
I do the resizing in a while loop but the problem is when i decrease the width and height of the picture the file size increases. At a certain point the size gets smaller but at the cost of quality
Request.InputStream.Position = 0;
string Data = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
var Base64 = Data.Split(',')[1];
var BitmapBytes = Convert.FromBase64String(Base64);
var Bmp = new Bitmap(new MemoryStream(BitmapBytes));
while (BitmapBytes.Length > 51200)
{
int Schritte = 20; //I tested here also with 300
int maxWidth = Bmp.Width;
maxWidth = maxWidth - Schritte;
int maxHeight = Bmp.Height;
maxHeight = maxHeight - Schritte;
Bmp = ScaleImage(Bmp, maxWidth, maxHeight);
var base64 = ReturnImageAsBase64(Bmp);
BitmapBytes = Convert.FromBase64String(base64);
}
The Code to resize:
public static Bitmap ScaleImage(Image image, int maxWidth, int maxHeight)
{
var ratioX = (double)maxWidth / image.Width;
var ratioY = (double)maxHeight / image.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(image, new Rectangle(0, 0, newWidth, newHeight));
}
return newImage;
}
I start with a Size of 66964 Bytes. After the first turn in the loop its 85151 Bytes and this although the width was reduced by 300 pixel and the height by 420 pixel.
From my comment earlier:
I would say that is a Problem of your Pixelformat. If you have for example a Bitmap with 1bpp (black or white) and draw that to your newImage in ScaleImage, the newImage is created with the default Pixelformat which is likely with Colors so you end up with 24bpp which results in a much higher Memory size.
Try changing:
Bitmap newImage = new Bitmap(newWidth, newHeight);
to
Bitmap newImage = new Bitmap(newWidth, newHeight, image.PixelFormat);
Edit: As the use of indexed PixelFormats seem to be impossible to create a graphics object from, there seems to be no easy solution on this.
To explain the reason for the bigger Image size:
Original Image:
Color lookup table:
1 = Red = 255, 0,0
2 = Black = 0, 0,0
3 = Green = 0,255,0
...
Column
Row 1 2 3 4
1 1 1 1 1
2 1 1 1 1
3 2 2 2 2
4 3 3 3 3
Here you have 16 Bytes for 16 Pixels and 12 Bytes for the lookup table (one byte for the index number and three bytes for the RGB channels for each color)
So the total size of the Image is 28 Bytes
In the newImage there is no lookup table so each Pixel has the full RGB information:
Column
Row 1 2 3 4
1 (255, 0,0) (255, 0,0) (255, 0,0) (255, 0,0)
2 (255, 0,0) (255, 0,0) (255, 0,0) (255, 0,0)
3 ( 0, 0,0) ( 0, 0,0) ( 0, 0,0) ( 0, 0,0)
4 ( 0,255,0) ( 0,255,0) ( 0,255,0) ( 0,255,0)
So the size of the newImage is 3*16=48 Bytes

Rescaling image causes loss of pixels

I seem to be having trouble up-scaling an image that is 8x8 pixels. When testing, I wanted to scale the image up to 64x64 pixels. However, when doing so, this was the result:
Rescaling it the way I did below, removes 4 pixels height on the top, and 4 pixels width on the left, and adds 4 black pixels height on the bottom, and 4 pixels width on the right.
Here is the code I am using to rescale the image:
private static Image ScaleImage(string username, int size)
{
Image avatar = MergeImage(username);
int originalWidth = avatar.Width;
int originalHeight = avatar.Height;
float ratioX = (float)size / (float)originalWidth;
float ratioY = (float)size / (float)originalHeight;
float ratio = Math.Min(ratioX, ratioY);
int newWidth = (int)(originalWidth * ratio);
int newHeight = (int)(originalHeight * ratio);
Bitmap newImage = new Bitmap(newWidth, newHeight, PixelFormat.Format48bppRgb);
using (Graphics g = Graphics.FromImage(newImage))
{
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(avatar, 0, 0, newWidth, newHeight);
}
return newImage;
}
I am unsure of what is going wrong here. Any help would be greatly appreciated.
Add this before g.DrawImage:
g.PixelOffsetMode = PixelOffsetMode.Half;

How do I resize an image without stretching it?

I am trying to resize an image (bitmap) in C# without stretching the image.
Say the image is 100x100 pixels.
I am looking to make it 100x110 pixels, and leave a white gap at the bottom of the image where it added the extra pixels.
I have done this, but cannot find a way to specify the pixel format. I need it to be 8bppindexed. I've attached an example to show the before and after image.
Here is the code I have so far.
string visit2 = "C:\\users\\moorez\\desktop\\visit2.bmp";
Bitmap orig = new Bitmap(visit2);
int width = orig.Width;
int height = orig.Height;
int newHeight = height + 2;
Bitmap newImage = orig.Clone(new Rectangle(0, 0, width, height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
newImage.Save("C:\\users\\moorez\\desktop\\visit3.bmp");
Bitmap test = new Bitmap(width, newHeight);
Graphics g = Graphics.FromImage(test);
g.DrawImage(newImage, new Point(0, 0));
test.Save("C:\\users\\moorez\\desktop\\visit4.bmp");
You can try this
Bitmap bmp = new Bitmap(newImage.Width, newHeight);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
g.DrawImageUnscaled(newImage, 0, 0, newImage.Width, newHeight);
bmp.Save(#"C:\\users\\moorez\\desktop\\visit3.bmp", ImageFormat.Jpeg);

Categories