I am using a method that i got from internet and I customized it a little bit.
it takes a HttpPostedFile from fileUpload and some not necessary parameters and then resize the image and comperise it then saving it in the hosting and returning the location
but after I uploaded the image I found it become a little bit gray and you can see the difference in the two pictures here.
Real Image:
Uploaded Image
how I can fix that in my method.
My Upload Method
public string ResizeImage(HttpPostedFile PostedFile, string destinationfile, int maxWidth, int maxHeight)
{
float ratio;
// Create variable to hold the image
System.Drawing.Image thisImage = System.Drawing.Image.FromStream(PostedFile.InputStream);
// Get height and width of current image
int width = (int)thisImage.Width;
int height = (int)thisImage.Height;
// Ratio and conversion for new size
if (width < maxWidth)
{
ratio = (float)width / (float)maxWidth;
width = (int)(width / ratio);
height = (int)(height / ratio);
}
// Ratio and conversion for new size
if (height < maxHeight)
{
ratio = (float)height / (float)maxHeight;
height = (int)(height / ratio);
width = (int)(width / ratio);
}
// Create "blank" image for drawing new image
System.Drawing.Bitmap outImage = new System.Drawing.Bitmap(width, height);
System.Drawing.Graphics outGraphics = System.Drawing.Graphics.FromImage(outImage);
System.Drawing.SolidBrush sb = new System.Drawing.SolidBrush(System.Drawing.Color.White);
outGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
outGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
outGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// Fill "blank" with new sized image
outGraphics.FillRectangle(sb, 0, 0, outImage.Width, outImage.Height);
outGraphics.DrawImage(thisImage, 0, 0, outImage.Width, outImage.Height);
sb.Dispose();
outGraphics.Dispose();
thisImage.Dispose();
if (!destinationfile.EndsWith("/"))
destinationfile += "/";
if (!System.IO.Directory.Exists(Server.MapPath(destinationfile)))
System.IO.Directory.CreateDirectory(Server.MapPath(destinationfile));
// Save new image as jpg
string filename = Guid.NewGuid().ToString();
outImage.Save(Server.MapPath(destinationfile + filename + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
outImage.Dispose();
return destinationfile + filename + ".jpg";
}
EDIT
I took a print screen so you can see the difference in color between the two picture
The main difference between the images when it comes to color, is that the original image doesn't have a color profile at all, while the processed image has the sRGB color profile.
Depending on the browser, the operating system, and how your screen is calibrated, the images will be shown with slightly different colors. For the image without a color profile, the browser can either assume a color profile for it, or it can display it without any color correction at all. When I view the images in Firefox on my computer that has a color calibrated screen, I actually can't see any color difference at all.
The JPEG encoder has assumed the sRGB color profile when you save the image, which is as good a guess as any other profile when there is no color profile information at all in the original image. You need to upload an image with a color profile to see if the JPEG encoder handles that correctly or not. As long as there is no color profile, there is no right or wrong when it comes to interpreting the color values in the image.
Related
I'm loading the image dynamically to a pre-existing PictureBox person_img that has all default values and is not sized correctly. I'm expecting to be able to do the sizing dynamically so that all images are 1/3 of people_popup_tab width.
I've tried many ways, including answers from similar questions. My last attempt was to load the image and set the SizeMode to AutoSize so that it would first get rendered at its full size, then I'd be able to get its width and height this way. Then I would use this width and height to know how to proportionately scale the image down.
But the image still renders all wonky. Some also simply don't show up now.
How can I resize the image to 1/3 of people_popup_tab width without losing aspect ratio?
My current code:
person_img.SizeMode = PictureBoxSizeMode.AutoSize;
person_img.Load(thisFaculty.imagePath);
int oldWidth = person_img.Width;
int oldHeight = person_img.Height;
int newWidth = people_popup_tab.Width / 3;
int newHeight = oldHeight * (newWidth / oldWidth);
person_img.SizeMode = PictureBoxSizeMode.StretchImage;
person_img.Width = newWidth;
person_img.Height = newHeight;
First load the image to Bitmap class, than resize your picture box using the real dimensions of the image. Similar to below code
var bmp = new Bitmap(imageFile);
pictureBox1.Width = bmp.Width / 3;
pictureBox1.Height = bmp.Height / 3;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = bmp;
I want to center a background image. However the background image is larger than my control(which is a flat style checkbox).
A picture to make my problem clear
Usually if the background image is smaller than the control, it will be shown like the black box(which is properly centered); but in my case it will show partial image in the green box(left top corner), but the end result I want is the orange box(the center of the image), or zoomed proportionally to fill the control with extra part cut off(ImageLayout.Zoom will show whole image with blank space).
Update: Code used:
Image img = Image.FromFile("xxxx.png");
mycheckbox.BackgroundImage = img;
mycheckbox.BackgroundImageLayout = ImageLayout.Center;
Image can be used instead of BackgroundImage to get the part of the image as the orange rectangle of the example.
If the image doesn't fill the entire checkbox and if it's acceptable to alter the image being set (should work without problems, but would not be dynamic in case the checkbox size changes during runtime), the image could be resized first according to the largest ratio:
var img = Image.FromFile("xxxx.png");
float ratio = Math.Max(mycheckbox.Height / (float)img.Height,mycheckbox.Width / (float)img.Width);
if (ratio > 1)
{
Func<float, int> calc = f => (int)Math.Ceiling(f * ratio);
var bmp = new Bitmap(img, calc(img.Width ), calc(img.Height ));
img.Dispose();
img = bmp;
}
mycheckbox.ImageAlign = ContentAlignment.MiddleCenter;
mycheckbox.Image = img;
The line float ratio = Math.Max(mycheckbox.Height / (float)img.Height,mycheckbox.Width / (float)img.Width); simply calculates both the height ratio and the width ratio. If either is larger than 1, it means the checkbox height or width is larger. It doesn't matter which one, only which is larger, hence the Math.Max. The check of larger than 1 is performed on the largest ratio and if needed the image is enlarged with said ratio.
Edit A more generic approach, that scales and cuts the image so that if fills the control size and the BackGroundImage property can be used:
public static void SetImage(this Control ctrl, Image img)
{
var cs = ctrl.Size;
if (img.Size != cs)
{
float ratio = Math.Max(cs.Height / (float)img.Height, cs.Width / (float)img.Width);
if (ratio > 1)
{
Func<float, int> calc = f => (int)Math.Ceiling(f * ratio);
img = new Bitmap(img, calc(img.Width), calc(img.Height));
}
var part = new Bitmap(cs.Width, cs.Height);
using (var g = Graphics.FromImage(part))
{
g.DrawImageUnscaled(img, (cs.Width - img.Width) /2, (cs.Height - img.Height) / 2);
}
img = part;
}
ctrl.BackgroundImageLayout = ImageLayout.Center;
ctrl.BackgroundImage = img;
}
i generate picture according to the size of picture box and set the picture to picture box whose size mode is normal but full image is not showing rather few area of picture is cutting off. i want to generate picture in such a way as a result when i will set the picture on picture box then full image should be display. here is my code by which i generate picture
new Bitmap _lastSnapshot = new Bitmap(261, 204);
this.DrawToBitmap((Bitmap)_lastSnapshot, new Rectangle(Point.Empty, ((Bitmap)_lastSnapshot).Size));
261, 204 is size of picture box and picture size mode is normal.i assign the lastSnapshot to picture box after generation but full picture is not displaying.
i got a routine to resize image according to picture box size. it works well but image looks become obscure or unclear.i have to set the picturebox size mode stretch to fill up the image into pic box.
here is the routine i use to resize picture according to picture box size.
public static Image ResizeImage(Image image, Size size,
bool preserveAspectRatio = true)
{
int newWidth;
int newHeight;
if (preserveAspectRatio)
{
int originalWidth = image.Width;
int originalHeight = image.Height;
float percentWidth = (float)size.Width / (float)originalWidth;
float percentHeight = (float)size.Height / (float)originalHeight;
float percent = percentHeight < percentWidth ? percentHeight : percentWidth;
newWidth = (int)(originalWidth * percent);
newHeight = (int)(originalHeight * percent);
}
else
{
newWidth = size.Width;
newHeight = size.Height;
}
Image newImage = new Bitmap(newWidth, newHeight);
using (Graphics graphicsHandle = Graphics.FromImage(newImage))
{
graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsHandle.DrawImage(image, 0, 0, newWidth, newHeight);
}
return newImage;
}
call the routine
ResizeImage(value,pictureBox1.Size,true);
can anyone give some advise to generate and resize the picture for fit into picture box with good crystal clear image. thanks
If you want to preview of image in picturebox according to picturebox size then:
Change PictureBox property SizeMode to Zoom.
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
I'am using PictureBox for displaying images. My images are direct from scanner so the resolutions are up to 4000*4000... Because my display area is a lot smaller I have to display the image with pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; to preserve aspect ratio.
After that the image is in the middle of the screen.
How can I find the distance between the left side of the image control and the REAL left side of an actual image (see image bellow).
Is there any solution?
Btw. displaying the image on the left side of the screen would do the trick too.
var imageHeight = pictureBox1.Image.Height;
var imageWidth = pictureBox1.Image.Width;
var userSelection = rect.Rect;
var display = pictureBox1.DisplayRectangle;
var xFactor = (float)userSelection.Width / display.Width;
var yFactor = (float)userSelection.Height / display.Height;
var realCropSizeWidth = xFactor * imageWidth;
var realCropSizeHight = yFactor * imageHeight;
var realCropX = imageWidth / display.Width;
realCropX *= userSelection.X;
var realCropY = imageHeight / display.Height;
realCropY *= userSelection.Y;
var realCropRectangle = new Rectangle(realCropX, realCropY, (int)realCropSizeWidth,
(int)realCropSizeHight);
var image = CropImage(pictureBox1.Image, realCropRectangle);
pictureBox1.Image = image;
public Image CropImage(Image source, Rectangle rectangle)
{
var target = new Bitmap(rectangle.Width, rectangle.Height);
using (var g = Graphics.FromImage(target))
{
g.DrawImage(source, new Rectangle(0, 0, target.Width, target.Height),
rectangle,
GraphicsUnit.Pixel);
}
return target;
}
As far as I know there is no direct way of getting what you want, but some simple maths would suffice:
You know the aspect ratio of your original image which is preserved and you know the aspect ratio of your picturebox in which you are showing it. Based on that you can figure out which dimension (height or width) the image fits exactly. Once you know that you can obtain the scaling factor of the image and therefore you can calculate the other dimension of the shown image.
As the image will be centered on the dimension that is not fitted exactly to the picturebox, its straighforward to get the distance you are looking for.
This is a follow up question on Save image to file keeping aspect ration in a WPF app
I know howto scale the image, but how do I expand the canvas size, to ensure the image still has the requested width and height. In this example its 250x250 but its dynamic.
I have created this illustration to show what I'm trying to accomplice.
I can't find any way of expanding the canvas of an BitmapImage, nor a way to create an in memory image in the correct size, with a transparent background, and then merging the two images together.
CroppedBitmap doesn't seem to support adding space around an image so instead you can create a transparent image the correct size using WriteableBitmap. If the input is smaller than the target size this method will enlarge it, but that is easy to alter.
public static BitmapSource FitImage(BitmapSource input, int width, int height)
{
if (input.PixelWidth == width && input.PixelHeight == height)
return input;
if(input.Format != PixelFormats.Bgra32 || input.Format != PixelFormats.Pbgra32)
input = new FormatConvertedBitmap(input, PixelFormats.Bgra32, null, 0);
//Use the same scale for x and y to keep aspect ratio.
double scale = Math.Min((double)width / input.PixelWidth, height / (double)input.PixelHeight);
int x = (int)Math.Round((width - (input.PixelWidth * scale))/2);
int y = (int)Math.Round((height - (input.PixelHeight * scale))/2);
var scaled = new TransformedBitmap(input, new ScaleTransform(scale, scale));
var stride = scaled.PixelWidth * (scaled.Format.BitsPerPixel / 8);
var result = new WriteableBitmap(width, height, input.DpiX, input.DpiY, input.Format,null);
var data = new byte[scaled.PixelHeight * stride];
scaled.CopyPixels(data, stride, 0);
result.WritePixels(new Int32Rect(0,0,scaled.PixelWidth,scaled.PixelHeight), data, stride,x,y);
return result;
}
If you are already rendering content using RenderTargetBitmap you could wrap it in a ViewBox to do the scaling but if you're just working with normal images I'd use the above method.
You should be able to set the Stretch property to Uniform.
Just some code in case others are trying to postprocess files from a form upload.
if (file.PostedFile != null)
{
//write the new file to disk
string cachePath = String.Format("{0}temp\\", Request.PhysicalApplicationPath);
string photoPath = String.Format("{0}temp.png", cachePath);
if (!Directory.Exists(cachePath))
{
Directory.CreateDirectory(cachePath);
}
file.PostedFile.SaveAs(photoPath);
//resize the new file and save it to disk
BitmapSource banana = FitImage(ReadBitmapFrame(file.PostedFile.InputStream), 640, 480);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(banana));
FileStream pngStream = new FileStream(cachePath + "test.png", FileMode.Create);
encoder.Save(pngStream);
pngStream.Close();
//set a couple images on page to the newly uploaded and newly processed files
image.Src = "temp/temp.png";
image.Visible = true;
image2.Src = "temp/test.png";
image2.Visible = true;
}