Pls. suggest how to set an image's width & Height Property while saving Images
If you want to save bitmap with some specific width and height (which differ from the Width and Height properties of the bitmap), you need to create a new Bitmap of corresponding size and draw the initial bitmap in needed size on it.
Like this:
using (Bitmap bmpToSave = new Bitmap(1000, 500)) {
using (Graphics g = Graphics.FromImage(bmpToSave)) {
g.DrawImage(bmp, 0, 0, 1000, 500);
}
bmpToSave.Save(#"bitmap.bmp");
}
Where bmp is your original bitmap.
Also, read up on some options that affect the quality of resampling if you need the high quality result.
Related
I have bitmap residing in memory (coming from my webcam but I don't think that this makes a difference.
It is 960x540 120dpi
you see that the picture in the lower part gets till the point where my shirt begins.
I know the bmp dimensions since I put this code prior resize
using (var fileStream = new FileStream(#"C:\temp\3.bmp", FileMode.Create))
{
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(source));
encoder.Save(fileStream);
}
and the result is the picture above.
Then I resize it with that:
var resizedImage = new RenderTargetBitmap(
width, height, // Resized dimensions 200x112
source.DpiX, source.DpiY,// Default DPI values
PixelFormats.Default); // Default pixel format
and the result is the bmp below which is properly 200x112 but it cuts out in part of the image in the lower and right part.
I have seen that the problem is related with the dpi value in the RenderTargetBitmap instruction. If I divide the dpi by 1.25 everything gets fine but why 1.25???????
Thank you in advance for any help
Patrick
--ADD--
There is something additional that I can't understand: I know the initial bitmap size for I have saved it to filesytem with the instructions above.
But if I look at the properties by putting a breakpoint I see:
BITMAP BEFORE RESIZE
width,height = 768, 432
pixelwidth, pixelheight = 960, 540
dpiX, dpiY= 120, 120
BITMAP AFTER RESIZE
width,height = 160, 89
pixelwidth, pixelheight = 200, 112
dpiX, dpiY= 120, 120
now I know that what counts here is pixelwidth, pixelheight so that's correct.
If I do 960/786 I get 1.25! So that's my number but why? Can I correct the code as to make it a general solution???
Instead of a RenderTargetBitmap you should simply use a TransformedBitmap with an appropriate ScaleTransform:
var scale = 200d / 960d;
var resizedImage = new TransformedBitmap(source, new ScaleTransform(scale, scale));
I am working on Windows 8 Phone app, I have some images displaying in my app, the images which I have are very big with good quality, now in my app I need to resize the image without disturbing the aspect ratio.
I have searched for it and couldnt find a suitable soultion.
How to achieve this?
Here is my code in .CS file.
string imageName= "path to folder" + name + ".png";
BitmapImage bmp = new BitmapImage(new Uri(imageName, UriKind.Relative));
Image.Source = bmp;
EDIT
More info: Currently i am displaying images in my List Box, so the images are looking very big, so i want to decrease it to lower size without affecting the aspect ratio of the image.
If you want to load reduced image into memory then set DecodePixelWidth without setting
DecodePixelHeight (or other way round)
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.DecodePixelWidth = 80;
bitmapImage.UriSource = new Uri(imageName, UriKind.Relative);
EDIT
Or if you want to keep high resolution image in memory set size for Image control.
<Image ... Width="80"/>
Stretch property is set by default to Uniform which means:
The content is resized to fit in the destination dimensions while it preserves its native aspect ratio.
This should do:
static void Main(string[] args)
{
int _newWidth = 60; //the new width is set, the height will be calculated
var originalImage = Bitmap.FromFile(#"C:\temp\source.png");
float factor = originalImage.Width / (float)_newWidth;
int newHeight = (int)(originalImage.Height / factor);
Bitmap resizedImage = ResizeBitmap(originalImage, _newWidth, newHeight);
resizedImage.Save(#"c:\temp\target.png");
}
private static Bitmap ResizeBitmap(Image b, int nWidth, int nHeight)
{
Bitmap result = new Bitmap(nWidth, nHeight);
using (Graphics g = Graphics.FromImage(result))
g.DrawImage(b, 0, 0, nWidth, nHeight);
return result;
}
If you want to reduce image size proportionally on display, try to play with Image control's Stretch property as demonstrated and explained very well in this blog post.
<Image x:Name="Image" Stretch="UniformToFill"></Image>
The size of an image element is influenced by its containing panel, but this should work in any panel.
<Grid>
<Image Source='flower.png' Width='120' Stretch='Uniform'/>
</Grid>
I'd like to take a bitmap with an ARGB 32 pixel format and clip it so that the contents within its inscribed ellipse remain, and anything outside the ellipse turns into ARGB(0,0,0,0).
I could do it programmatically using GetPixel and SetPixel and some trigonometry to figure out which pixel is out of bounds - but I suspect there's a better, more built-in way to do it.
Any ideas?
Thanks to Alessandro D'Andria for pointing out the region part - I've figured out the rest:
public Bitmap Rasterize()
{
Bitmap ringBmp = new Bitmap(width: _size.Width, height: _size.Height, format: PixelFormat.Format32bppArgb);
//Create an appropriate region from the inscribed ellipse
Drawing2D.GraphicsPath graphicsEllipsePath = new Drawing2D.GraphicsPath();
graphicsEllipsePath.AddEllipse(0, 0, _size.Width, _size.Height);
Region ellipseRegion = new Region(graphicsEllipsePath);
//Create a graphics object from our new bitmap
Graphics gfx = Graphics.FromImage(ringBmp);
//Draw a resized version of our image to our new bitmap while using the highest quality interpolation and within the defined ellipse region
gfx.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor;
gfx.SmoothingMode = Drawing2D.SmoothingMode.HighQuality;
gfx.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality;
gfx.PageUnit = GraphicsUnit.Pixel;
gfx.Clear(Color.Transparent);
gfx.Clip = ellipseRegion;
gfx.DrawImage(image: _image, rect: new Rectangle(0, 0, _size.Width, _size.Height));
//Dispose our graphics
gfx.Dispose();
//return the resultant bitmap
return ringBmp;
}
Apparently it is extremely important to set PixelOffsetMode to HighQuality, because otherwise the DrawImage method would crop parts of the resulting image.
using (var mem = new MemoryStream())
using (var bmp = new Bitmap(85, 54))
using (var gfx = Graphics.FromImage((Image)bmp))
{
// gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.PageUnit = GraphicsUnit.Millimeter;
gfx.FillRectangle(Brushes.Red, new Rectangle(0, 0, bmp.Width, bmp.Height));
//add question
gfx.DrawString(captcha, new Font("Arial", 5), Brushes.Blue, bmp.Width / 2, bmp.Height/2);
//render as Jpeg
bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg);
img = this.File(mem.GetBuffer(), "image/Jpeg");
}
return img;
this not work.
I need 85x54 millimeter
how do this?
I need draw for print
The size of this Bitmap is in pixels.
When you display a bitmap on a regular display a single pixel will be 1/96th of an inch. Other displays might have other DPI's (Dots Per Inch) - such as Retina displays
Most printers support at least 300 DPI.
So what you need to do is get the DPI of the screen or printer and size the bitmap accordingly or use a image format (vector?) that allows you to specify the DPI. Some bitmap formats also allow you to specify the intended DPI
Digital images are always in pixels. Never in millimeters or inches. Depending on the DPI (dots per inch) you'll use when printing, the pixels are translated to millimeters or inches.
For screen, use 72 pixels per inch, for print use 300.
For your picture (85x54mm = 3.34x2.12in) use (3.34 * 300) x (2.12 * 300) = 1002 x 637 pixels for print.
Does anyone know how to create a new bitmap from an existing image with a taller height, but don't scale the image and just have transparent, black or white below the original image in the new bitmap?
I basically have one picture that is taller than the second and I need the second one to be as tall as the first, without stretching it.
img2 = new Bitmap(lImages[2],new Size(pictureBox.Image.Width,pictureBox.Image.Height));
img2 = ((Bitmap)img2).Clone(new Rectangle(0, 0, pictureBox.Image.Width, pictureBox.Image.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
C# .NET 4.0.
By using a Graphics object, you can achieve this easily:
Bitmap temp = new Bitmap(new Size(pictureBox.Image.Width,pictureBox.Image.Height));
using(Graphics g = Graphics.FromImage(temp))
{
g.DrawImage(img2, 0, 0);
}
img2 = temp;
Now img2 references a new Bitmap object of the required size which has the original (unstretched) image painted on it.
Note: To control the color of the extra space, add a call to g.FillRect before drawing the image.
Create your "standart" size bitmap and fill it with, let's say, white color and call Bitmap.MakeTransparent(Color.White) and draw your final image over it.