I have a problem with standard Graphics on picturebox.Actually my picturebox image size is x = ~5000 y= ~3000. If I use
Graphics gr = Picturebox1.Creategraphics();
Everything disappear when scrolling. Else if i use Graphics gr = Graphics.FromImage(Picturebox1.Image);
I always need to reload picture,but this is very uncomfortable.I want that Picturebox image refreshes when user "says".I found some graphics dll but they don't work.How can i draw what say above correctly?
I'm guessing you still haven't looked in to the paint event handler, so just do this:
private void Form1_Paint(object sender, PaintEventArgs e)
{
string fileLocation = "Get File Location"; //WHERE IS THE IMAGE LOCATED? DON'T FORGET FILE EXTENTIONS!!
//Graphics g = e.Graphics; //GRAPHICS INSTANCE
Image img = Image.FromFile(fileLocation); //IMAGE INSTANCE
// IF YOU PLACED A PICTUREBOX IN YOUR FORM.
Size maxSize = new Size(); //CREATE SIZE MAXIMUMS FOR THE LARGEST YOU WANT AN IMAGE TO BE
Size imgSize = new Size(); //FIND THE IMAGE SIZE FOR COMPARISON
maxSize.Width = 600; //SET MAX WIDTH
maxSize.Height = 600; //SET MAX HEIGHT
imgSize.Width = img.Width; //FIND IMAGE WIDTH
imgSize.Height = img.Height; //FIND IMAGE HEIGHT
pbImage.MaximumSize = maxSize; //MAKE SURE WE DONT GO PAST OUR MAX SIZE
pbImage.BackgroundImageLayout = ImageLayout.Stretch; //MAKE SURE THE IMAGE STRETCHES TO THE SIZE OF THE PICTURE BOX
//HERE, WE RUN A SERIES OS CHECKS TO SEE HOW BIG TO MAKE OUR PICTURE BOX
if (imgSize.Height < maxSize.Height && imgSize.Width < maxSize.Width) //IF THE PICTURE IS SMALLER THAN THE MAX SIZE
pbImage.Size = imgSize; //SET THE SIZE TO THAT OF THE PICTURE
else if (imgSize.Height > maxSize.Height || imgSize.Width > maxSize.Width) //IF THE WIDTH OR HEIGHT ARE LARGER THAN THE MAX
{
//SET HEIGHT
if (imgSize.Height < maxSize.Height)
pbImage.Height = imgSize.Height;
else pbImage.Height = maxSize.Height;
//SET WIDTH
if (imgSize.Width < maxSize.Width)
pbImage.Width = imgSize.Width;
else pbImage.Width = maxSize.Width;
}
else if (imgSize.Height > maxSize.Height && imgSize.Width > maxSize.Width) //IF THE IMAGE IS BIGGER THAN OUR MAX
pbImage.Size = maxSize; //MAKE IT THE SIZE OF THE MAX
pbImage.Image = img; //PUT THE IMAGE IN THE BOX
// IF YOU DIDN'T - YOU SHOULD. IT'S FAR MORE CONTROLLED
//g.DrawImage(img, 0, 0, (float)img.Width, (float)img.Height);
}
Hope that helps. Obviously modify the string value for fileLocation and the max width and height to your liking. Anything past this, do more research:
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.paint.aspx
https://msdn.microsoft.com/en-us/library/system.drawing.graphics(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.windows.forms.picturebox(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.windows.controls.image.aspx
Related
Im trying to take an input from a webcam and only want the centre of the image (to passport size image).
I have a Picturebox with the webcam stream which I have set SizeMode to CentreImage. I then have a second picturebox which when I click the second picturebox i then need a cropped image i then save later (currently i get the whole original image when saving).
I have code to crop this image into the 2nd picturebox which works however it loses loads of quality. Is there a way to make this crop lossless?
private void pictureBox1_Click(object sender, EventArgs e)
{
//picPhoto.Image = pic.Image;
using (Bitmap bmp = new Bitmap(pic.Image))
{
var newImg = bmp.Clone(
new Rectangle { X = ((pic.Image.Width/2)-(350/2)), Y = ((pic.Image.Height / 2) - (450 / 2)), Width = 350, Height = 450 },
bmp.PixelFormat);
picPhoto.Image = newImg;
}
}
When i run the program, i get a different amount of images(from 20 all the way up to 2000) and i would like to merge all of these images into one image which would preferably be a square.
This is the code i have for getting the file images(the images are in URL format)
int ximg = 1;
int totalImgs = richTextBox1.Lines.Count();
while (ximg < totalImgs)
{
System.Net.WebRequest request = System.Net.WebRequest.Create(richTextBox1.Lines[ximg]);
System.Net.WebResponse response = request.GetResponse();
System.IO.Stream responseStream =
response.GetResponseStream();
Bitmap image = new Bitmap(responseStream);
List<Image> fileList = new List<Image>();
fileList.Add(image);
ximg++;
}
Also every single image has a title in a different richtextbox which i would like to know if it is possible to add a title under the image (richtextbox1.lines[1] (image) = richtextbox2.lines[1] (title)). Is it possible to add a picture as a background picture when merging(to the square image I want to generate)? Is it possible to add a border on every single image picture and merge them with the border? How can the code calculate when its time to change line and start adding images in the next row?
I've tried this code, but it works only if you know the amount of images you want to merge.
Bitmap bitmap = new Bitmap(image1.Width + image2.Width, Math.Max(image1.Height, image2.Height));
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawImage(image1, 0, 0);
g.DrawImage(image2, image1.Width, 0);
}
bitmap.Save("merged.bmp");
I would do it with photoshop but when there are 2000 images to merge together, I just do not have the time.
Is there any way to accomplish such task? Any references would be appreciated!
I have mentioned it above :) !
This solution will create a mosaic of the images from left to right, top to bottom. It does not do anything to maximize the available space. It also assumes that you have a max width and height for the finished image, since it's not realistic to support an arbitrary size.
// where we store the finished mosaic
var mosaic = new Bitmap(maxWidth, maxHeight);
// track the location where we are drawing each image
var imageCorner = new Point(0,0);
// track the height of the current row
var currentRowHeight = 0;
// track the width and height of the mosaic as it grows.
var mosaicWidth = 0;
var mosaicHeight = 0;
using (var g = Graphics.FromImage(bitmap))
{
var borderPen = new Pen(Brushes.Black) { Width = 2 };
var labelFont = new Font("Arial", 10);
var labelBrush = new SolidBrush(Color.Black);
foreach (var image in imageList)
{
if (imageCorner.X + image.Width > maxWidth)
{
// if adding the image to the current row would make it too wide,
// move to the next row by resetting X to zero and adding the
// height of the tallest image to Y
imageCorner.X = 0;
imageCorner.Y += currentRowHeight;
// since this is a new row, it's current height is zero
currentRowHeight = 0;
}
// if adding this image would put us past the
// height of the image, then we're out of room.
if (imageCorner.Y + image.Height > maxHeight)
{
// this skips images if there's no room for them in
// the mosaic, you may want to do something different
Trace.WriteLine($"Image is {image.Height} pixels tall, but only {maxHeight - mosaicHeight} pixels available.");
continue;
}
// draw the image
g.DrawImage(image, imageCorner);
// draw the border
g.DrawRectangle(borderPen,
imageCorner.X, imageCorner.Y,
image.Width, image.Height)
// draw the label
g.DrawText("Image Label", labelBrush, imageCorner.X, imageCorner.Y)
// now that we've drawn the image, we need to shift to the right
imageCorner.X += image.Width;
// row height is the height of the tallest image so far in this row
currentRowHeight = Math.Max(image.Height, currentRowHeight);
// track the total height of the mosaic
mosaicHeight = imageCorner.Y + currentRowHeight;
// mosaic width is just the widest row in the mosaic
mosaicWidth = Math.Max(imageCorner.X, widthOfWidestRow);
}
}
// trim off the parts of the mosaic we didn't fill
mosaic = mosaic.Clone(new Rectangle(0, 0, mosaicWidth, mosaicHeight);
mosaic.Save("merged.bmp");
If you wanted to minimize wasted space, you could sort your list of images in different ways, or calculate ahead of time what a good width and height for the mosaic would be.
I have an image control in my webform. I set its width 100px and height 100px. but if someone upload an image of ratio 100 * 120. I want it crop or resize and set 100 * 100. I tried to set max width but not worked , I tried bitmap method with code
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string filename = FileUpload1.FileName;
string directory = Server.MapPath("~/");
Bitmap originalBMP = new Bitmap(FileUpload1.FileContent);
float origWidth = originalBMP.Width;
float origHeight = originalBMP.Height;
float sngRatio = origWidth / origHeight;
float newWidth = 100;
float newHeight = newWidth / sngRatio;
Bitmap newBMP = new Bitmap(originalBMP,Convert.ToInt32(newWidth),Convert.ToInt32(newHeight));
Graphics oGraphics = Graphics.FromImage(newBMP);
oGraphics.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
oGraphics.InterpolationMode=System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
newBMP.Save(directory + filename);
originalBMP = null;
newBMP = null;
oGraphics = null;
Label1.Text = "File <b style='color: red;'>" + filename + "<</b> uploaded.";
Image1.ImageUrl = #"~/" + filename;
}
else
{
Label1.Text = "No file uploaded!";
}
}
it worked but it save the resized image in directery I want to save original image in directory and display the resize image in image control.
Check out Web Image Resize handler on codeplex : http://webimageresizer.codeplex.com/
It is a custom handler to process images.
Sample urls
Taken from the codeplex project's home page
// Returns the image mapping to /bla.jpg resized to width of 100 pixels preserving aspect relative to height
/ImageHandler.ashx?src=/bla.jpg&width=100
// Returns the image mapping to /bla.jpg resized to height of 100 pixels preserving aspect relative to width
/ImageHandler.ashx?src=/bla.jpg&height=100
// Returns the image mapping to /bla.jpg resized to width 100 pixels and a height of 50 pixels
/ImageHandler.ashx?src=/bla.jpg&width=100&height=50
Another option is to use http://imageresizing.net/
The benefit is that it registers a handler to handle images transparently, meaning, that you only add querystring variables to your original image url to manipulate the image.
Sample urls
/images/bla.jpg?h=100&w=100
The image has 200px width and the pictureBox has 400px.
Which property of pictureBox should I set to display the image repeat-x?
I don't think there is any property which makes the image display x times repeatedly horizontally. But a little custom code can help, here is my code:
public static class PictureBoxExtension
{
public static void SetImage(this PictureBox pic, Image image, int repeatX)
{
Bitmap bm = new Bitmap(image.Width * repeatX, image.Height);
Graphics gp = Graphics.FromImage(bm);
for (int x = 0; x <= bm.Width - image.Width; x += image.Width)
{
gp.DrawImage(image, new Point(x, 0));
}
pic.Image = bm;
}
}
//Now you can use the extension method SetImage to make the PictureBox display the image x-repeatedly
myPictureBox.SetImage(myImage, 3);//repeat 3 images horizontally.
You can customize the code to make it repeat vertically or look like a check board.
Hope it helps!
I loaded the jpg to picture box (in SizeMode as Zoom).
I drew a rectangle on the picture box and took the coordinate.
I opened the jpg in paint and observed the coordinate (where I drew the rectangle on the picture box).
When I compared the rectangle coordinates (x and y) with paint coordinates, they were not the same.
I changed the SizeMode to Normal and observed that the coordinates became the same, but the image size was too large so it was display partially, so I want to use Zoom SizeMode property.
Say image with size 2825x3538 and keep the picture box size mode as Normal, the image shows partially in picture box. So I changed picture box mode to Zoom (to fit the System screen resolution), and the coordinates missmatched when comparing it with Normal mode with SizeMode.
How can I achieve the same coordinates?
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFD.FileName = "";
OpenFD.Title = "open image";
OpenFD.InitialDirectory = "C";
OpenFD.Filter = "JPEG|*.jpg|Bmp|*.bmp|All Files|*.*.*";
if (OpenFD.ShowDialog() == DialogResult.OK)
{
file = OpenFD.FileName;
image = Image.FromFile(file);
pictureBox1.Image = image;
svc = Screen.PrimaryScreen;
pictureBox1.Width = svc.Bounds.Width;
pictureBox1.Height = svc.Bounds.Height - 100;
mybitmap1 = new Bitmap(pictureBox1.Image);
mybitmap1.SetResolution(300, 300);
pictureBox1.Image = mybitmap1;
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (mybitmap == null)
{
mybitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
mybitmap.SetResolution(300, 300);
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (g = Graphics.FromImage(mybitmap))
{
using (Pen pen = new Pen(Color.Green, m))
{
e.Graphics.DrawRectangle(pen, r);
e.Graphics.DrawString(lab[c].ToString(), new Font(lab[c].ToString(), 8F), new SolidBrush(label1.ForeColor), r);
}
}
}
You can use two scale factors between the actual image and the picture box, one with height and the other with width.