Hi I want to put products to a catalog, How i can crop the picture to small and save the small and the orginal?
Try look here:
C# Thumbnail Image With GetThumbnailImage
or here:
Convert Bitmap to Thumbnail
Create thumbnail and reduce image size
Create thumbnail image
update
For example you can save the image to a folder and then you can do something like this:
var filename = "sourceImage.png";
using(var image = Image.FromFile(filename))
{
using(var thumbnail = image.GetThumbnailImage(20/*width*/, 40/*height*/, null, IntPtr.Zero))
{
thumbnail.Save("thumb.png");
}
}
update
to resize proportionally try something like this:
public Bitmap ProportionallyResizeBitmap (Bitmap src, int maxWidth, int maxHeight)
{
// original dimensions
int w = src.Width;
int h = src.Height;
// Longest and shortest dimension
int longestDimension = (w>h)?w: h;
int shortestDimension = (w<h)?w: h;
// propotionality
float factor = ((float)longestDimension) / shortestDimension;
// default width is greater than height
double newWidth = maxWidth;
double newHeight = maxWidth/factor;
// if height greater than width recalculate
if ( w < h )
{
newWidth = maxHeight / factor;
newHeight = maxHeight;
}
// Create new Bitmap at new dimensions
Bitmap result = new Bitmap((int)newWidth, (int)newHeight);
using ( Graphics g = Graphics.FromImage((System.Drawing.Image)result) )
g.DrawImage(src, 0, 0, (int)newWidth, (int)newHeight);
return result;
}
Related
This might be a tricky question.
I will just cut to the chase.
First i make a blank Bitmap image:
Bitmap MasterImage = new Bitmap(PageSize.Width, PageSize.Height, PixelFormat.Format32bppArgb);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(MasterImage);
Afterwards:
I get a parameter of how much images i want to place in the Blank Bitmap (page) based on columns and rows:
int numOfColumns=2; //(could be any value)
int numOfRows=4;
So we should get something like this:
I also get a parameter if i have some margin at top image and left image:
int PagetopMargin=0; //(could be any value)
int PageLeftMargin=0;
Than i have a variable called: imagesPath which is type of List<String> it contains full path of images.
Now i loop through images:
while (imagesPath.Count > 0)
{
Image image = Image.FromFile(imagesPath[0]);
//Logic comes here.
//after finishing processing and drawing images in Bitmap i remove image from list
imagesPath.RemoveAt(0);
}
What i am trying to achieve is how to place maximum images in that Bitmap page based on column/row and margin variables and preserving aspect ratio of images. (so images wont get distorted). if some images are left behind, its okey, i will continue next blank Bitmap to place them. just need to fill the Bitmap blank image to the full.
Here is a function to fit a rectangle into another, either centered or uncentered (aligned top-left):
Rectangle FitToBox(Rectangle scr, Rectangle dest, bool centered)
{
var ratioX = (double)dest.Width / scr.Width;
var ratioY = (double)dest.Height / scr.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(scr.Width * ratio);
var newHeight = (int)(scr.Height * ratio);
if (!centered)
return new Rectangle(0, 0, newWidth, newHeight);
else
return new Rectangle((dest.Width - newWidth) / 2,
(dest.Height - newHeight) / 2, newWidth, newHeight);
}
Its basic math is taken form this post.
Here is a test bed, centered and uncentered using different random values:
Random rnd = new Random();
int cols = rnd.Next(3) + 2;
int rows = rnd.Next(4) + 3;
int w = pan_dest.Width / cols;
int h = pan_dest.Height / rows;
using (Graphics G = pan_dest.CreateGraphics())
{
G.Clear(Color.White);
for (int c = 0; c < cols; c++)
for (int r = 0; r < rows; r++)
{
Rectangle rDest = new Rectangle(c * w, r * h, w, h);
Rectangle rSrc = new Rectangle(0, 0, rnd.Next(200) + 10, rnd.Next(200) + 10);
Rectangle rResult = FitToBox(rSrc, rDest, checkBox1.Checked);
Rectangle rDestPlaced = new Rectangle(c * w + (int)rResult.X,
r * h + rResult.Y, rResult.Width, rResult.Height);
using (Pen pen2 = new Pen(Color.SlateGray, 4f))
G.DrawRectangle(pen2, Rectangle.Round(rDest));
G.DrawRectangle(Pens.Red, rDestPlaced);
G.FillEllipse(Brushes.LightPink, rDestPlaced);
}
}
You would then draw your images like this:
G.DrawImage(someImageimg, rDestPlaced, rSrc, GraphicsUnit.Pixel);
This maximizes the image sizes, not the number of images you can fit on a page, as specified in your comment. For the latter you should look into something like 2-dimensional packing..
I want to insert two different sizes of images using single file upload.
I had inserted one image which has size 101 but I need to insert another 51 size small image of the same user.
id BigImage SmallImage
1 mazhar.jpg NULL
2 mazhar.jpg NULL
3 12_n.jpg NULL
I need result like below:
id BigImage SmallImage
1 mazhar.jpg smallmazhar.jpg
2 mazhar.jpg smallmazhar.jpg
3 12_n.jpg small12_n.jpg
C# code is given below:
protected void Button1_Click(object sender, EventArgs e)
{
//http://forums.asp.net/t/1079883.aspx?PageIndex=1
string Status = string.Empty;
int id = 0;
const int bmpW = 101;
//New image target width
const int bmpH = 101;
//New Image target height
bo.Para1 = FileUpload1.FileName.ToString();// Passing parameter
if ((FileUpload1.HasFile))
{
//Clear the error label text
lblError.Text = "";
//Check to make sure the file to upload has a picture file format extention and set the target width and height
if ((CheckFileType(FileUpload1.FileName)))
{
Int32 newWidth = bmpW;
Int32 newHeight = bmpH;
//Use the uploaded filename for saving without the '.' extension
String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf("."));
//Set the save path of the resized image, you will need this directory already created in your web site
// string filePath = "~/Upload/" + upName + ".jpg";
bl.Insert_PhotoInfo(bo, out Status, out id);
string filePath = Convert.ToString(id) + bo.Para1;
FileUpload1.PostedFile.SaveAs(Request.ServerVariables["APPL_PHYSICAL_PATH"] + "Upload/" + filePath);
//Create a new Bitmap using the uploaded picture as a Stream
//Set the new bitmap resolution to 72 pixels per inch
Bitmap upBmp = (Bitmap)Bitmap.FromStream(FileUpload1.PostedFile.InputStream);
Bitmap newBmp = new Bitmap(newWidth, newHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
newBmp.SetResolution(72, 72);
//Get the uploaded image width and height
Double upWidth = upBmp.Width;
Double upHeight = upBmp.Height;
int newX = 0;
//Set the new top left drawing position on the image canvas
int newY = 0;
Double reDuce;
//Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions
//to ensure the image is always in the centre of the canvas vertically and horizontally
if (upWidth > upHeight)
{
//Landscape picture
reDuce = newWidth / upWidth;
//calculate the width percentage reduction as decimal
newHeight = ((Int32)(upHeight * reDuce));
//reduce the uploaded image height by the reduce amount
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
newX = 0;
//Picture will be full width
}
else if (upWidth < upHeight)
{
//Portrait picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = 0;
//Picture will be full hieght
}
else if (upWidth == upHeight)
{
//square picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
}
//Create a new image from the uploaded picture using the Graphics class
//Clear the graphic and set the background colour to white
//Use Antialias and High Quality Bicubic to maintain a good quality picture
//Save the new bitmap image using 'Png' picture format and the calculated canvas positioning
Graphics newGraphic = Graphics.FromImage(newBmp);
try
{
newGraphic.Clear(Color.White);
newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight);
newBmp.Save(MapPath(filePath), System.Drawing.Imaging.ImageFormat.Jpeg);
//Show the uploaded resized picture in the image control
Image1.ImageUrl = filePath;
Image1.Visible = true;
}
catch (Exception ex)
{
string newError = ex.Message;
lblError.Text = newError;
}
finally
{
upBmp.Dispose();
newBmp.Dispose();
newGraphic.Dispose();
}
}
else
{
lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png.";
}
}
}
try this
http://www.c-sharpcorner.com/UploadFile/99bb20/upload-multiple-files-using-fileupload-control-in-Asp-Net-4/
it should work for you
I need to crop an image without changing its aspect ratio. I am taking picture from CANON1100D using EDSDK. Captured image:
Width = 1920 and Height=1280
Aspect ratio is 1.5. But I need picture which aspect ratio will be 1.33.
// convert into processing resolution (1600,1200)
Image<Bgr, byte> runtime_frm = new Image<Bgr, byte>(frame.ToBitmap(1600,1200));
// also in bitmap processing
// Bitmap a = new Bitmap(runtime_frm.ToBitmap());
// Bitmap b = new Bitmap(a, new Size(1600,1200));
It's resizing the image, so the aspect ratio of image is changed, but it creates stress in image. I'd like to crop the image (1920x1280) to (1600x1200) in runtime.
How can I do this programmatically?
public void Crop(Bitmap bm, int cropX, int cropY,int cropWidth,int cropHeight)
{
var rect = new System.Drawing.Rectangle(cropX,cropY,cropWidth,cropHeight);
Bitmap newBm = bm.Clone(rect, bm.PixelFormat);
newBm.Save("image2.jpg");
}
Maybe something like that?
source
this is my solution for centered cropping.
Bitmap CenterCrop(Bitmap srcImage, int newWidth, int newHeight)
{
Bitmap ret = null;
int w = srcImage.Width;
int h = srcImage.Height;
if ( w < newWidth || h < newHeight)
{
MessageBox.Show("Out of boundary");
return ret;
}
int posX_for_centerd_crop = (w - newWidth) / 2;
int posY_for_centerd_crop = (h - newHeight) / 2;
var CenteredRect = new Rectangle( posX_for_centerd_crop,
posY_for_centerd_crop, newWidth, newHeight);
ret = srcImage.Clone(imageCenterRect, srcImage.PixelFormat);
return ret;
}
I have several problem with creating a bitmap from a array. I have a camera and from this I get grayscale values in ushort format. But how to create a bitmap from this values? Only:
System.Drawing.Bitmap checks = new System.Drawing.Bitmap(10, 10);
.
.
checks.Save(#"C:\test.bmp", ImageFormat.Bmp);
will not work:(. I get an image and can open it with window tools, but when I will open the file with another graphic lib, I get alot of errors. So does anybody now how to create a correct bmp file with header etc? does anybody have some code example? this would help most.
thanks
You should create a Bitmap with the right dimensions (width, height), and use LockBits to get a handle to memory that you should write to. If your data is in a .NET supported PixelFormat, you can pass that to LockBits and simply copy data. If not, you might have to do some data conversion manually.
It all boils down to what format you receive data samples in, but the above description outlines the steps you need to take to generate your image.
Update: Since your data is 16 bits gray scale, there is a PixelFormat you can use directly, PixelFormat.16bppGrayScale.
public class(path,wid,height,boolean)
{
System.Drawing.Image myThumbnail150;
System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
System.Drawing.Image imagesize = System.Drawing.Image.FromFile(pic.FilePath);
using (Bitmap bitmapNew = new Bitmap(imagesize))
{
double maxWidth = Convert.ToDouble(ConfigurationSettings.AppSettings["ImageWidth"]);
double maxHeight = Convert.ToDouble(ConfigurationSettings.AppSettings["ImageHeight"]);
int w = imagesize.Width;
int h = imagesize.Height;
// Longest and shortest dimension
int longestDimension = (w > h) ? w : h;
int shortestDimension = (w < h) ? w : h;
// propotionality
float factor = ((float)longestDimension) / shortestDimension;
// default width is greater than height
double newWidth = maxWidth;
double newHeight = maxWidth / factor;
// if height greater than width recalculate
if (w < h)
{
newWidth = maxHeight / factor;
newHeight = maxHeight;
}
myThumbnail150 = bitmapNew.GetThumbnailImage((int)newWidth, (int)newHeight, myCallback, IntPtr.Zero);
string name = pic.Name.Replace(Path.GetExtension(pic.Name), ".Bmp");
//Create a new directory name ThumbnailImage
//Save image in TumbnailImage folder
myThumbnail150.Save(yourpath+ name, System.Drawing.Imaging.ImageFormat.Bmp);
bitmapNew.Dispose();
}
A user will be able to upload an image. If the image is greater than a set size I want to downsize it to that size. Obviously it doesn't have to match exactly due to ratios, the width would be the key size so the height would be variable.
If the image is smaller than the set size I would like to create a new image to the set size with a background of a defined colour and then centre the uploaded image into it therefore the result is the original with paddded colour.
Any code examples or links greatly appreciated
Here's a snippet of code I quickly knocked up for resizing it based on the width. I'm sure you could figure out how to add a background color to the Bitmap. It's not complete code but just an idea of how to do things.
public static void ResizeLogo(string originalFilename, string resizeFilename)
{
Image imgOriginal = Image.FromFile(originalFilename);
//pass in whatever value you want for the width (180)
Image imgActual = ScaleBySize(imgOriginal, 180);
imgActual.Save(resizeFilename);
imgActual.Dispose();
}
public static Image ScaleBySize(Image imgPhoto, int size)
{
int logoSize = size;
float sourceWidth = imgPhoto.Width;
float sourceHeight = imgPhoto.Height;
float destHeight = 0;
float destWidth = 0;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
// Resize Image to have the height = logoSize/2 or width = logoSize.
// Height is greater than width, set Height = logoSize and resize width accordingly
if (sourceWidth > (2 * sourceHeight))
{
destWidth = logoSize;
destHeight = (float)(sourceHeight * logoSize / sourceWidth);
}
else
{
int h = logoSize / 2;
destHeight = h;
destWidth = (float)(sourceWidth * h / sourceHeight);
}
// Width is greater than height, set Width = logoSize and resize height accordingly
Bitmap bmPhoto = new Bitmap((int)destWidth, (int)destHeight,
PixelFormat.Format32bppPArgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, (int)destWidth, (int)destHeight),
new Rectangle(sourceX, sourceY, (int)sourceWidth, (int)sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
You can just load the file into a bitmap object:
http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx
Then just check the width on the object. For the second part of your problem, I would recommend using a tool like ImageMagick
http://www.imagemagick.org/script/index.php
to accurately resize the first image or to create the background image and merge the two images together.