Rendering the Bitmap in PictureBox control is very slow - c#

I've created a graph(Diagram) on PictureBox control. This control has the ability to zoom/pen. When I want to zoom, it slows down.
Thanks for helping someone
public void Render(bool resizeToo = false)
{
if (resizeToo)
{
plt.settings.Resize(pb.Width, pb.Height);
if (plt2 != null)
{
plt2.settings.Resize(plt.settings.width, plt.settings.height);
}
}
if (plt2 == null)
{
pb.Image = plt.figure.GetBitmap();
}
else
{
// if plt2 contains a GraphControl, match its X axis to the user control then overlay it
plt2.settings.axisX.Set(plt.settings.axisX.x1, plt.settings.axisX.x2);
Bitmap bmp1 = plt.figure.GetBitmap();
Bitmap bmp2 = plt2.figure.GetBitmap();
Bitmap bmpMerged = new Bitmap(bmp1);
using (Graphics gfx = Graphics.FromImage(bmpMerged))
gfx.DrawImage(bmp2, new Rectangle(0, 0, bmp2.Width, bmp2.Height));
pb.Image = bmpMerged;
}
Application.DoEvents();
}

Related

Merge Several Picture Box Image and Save

I currently work on image processing application. I have 'Main' PictureBox as canvas. I want to insert some PictureBox into 'Main' PictureBox and merge all as one Image then save it to png. This is my code. Can anybody help me to acccomplish this task please?
Bitmap bmp = new Bitmap(pictureEdit.Width, pictureEdit.Height);
bmp = (Bitmap)pictureEdit.Image;
foreach (Control c in pictureEdit.Controls)
{
if (c is Functions.pictureEdit)
{
using (var bitmap = new Bitmap(pictureEdit.Image.Width, pictureEdit.Image.Height)) {
using (var canvas = Graphics.FromImage(bitmap)) {
canvas.DrawImage(bmp, new Rectangle(0, 0, pictureEdit.Image.Width, pictureEdit.Image.Height));
canvas.DrawImage(((Functions.pictureEdit)c).img, new Rectangle(0, 0, pictureEdit.Image.Width, pictureEdit.Image.Height));
canvas.Save();
}
bitmap.Save(#"D:\Test\new.png", System.Drawing.Imaging.ImageFormat.Png);
}
}
}
Hope you are okay with Combining images together
Following code does that
private Bitmap CombineBitmap(List lstImages, int width, int height)
{
int iTilesPerWidth = 5;
//create a bitmap to hold the combined image
Bitmap finalImage = new System.Drawing.Bitmap(width, height);
//get a graphics object from the image so we can draw on it
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(finalImage))
{
PointF point1 = new PointF(0, 0);
int nCount = 1;
foreach (Bitmap BM in lstImages)
{
//512, 256
g.DrawImage(BM, point1);
point1.X += BM.Width;
if (nCount % iTilesPerWidth == 0)
{
point1.X = 0;
point1.Y += BM.Height;
}
nCount++;
}
}
return finalImage;
}

Crop image out of two points (C#)

Update:
Updated code added.
However for some reason it still doesn't work properly. If the coordinates are Bitmap coordinates, what could be the reason? The first code sample I put here doesn't work properly and the second gives me an OutOfMemoryException.
I've ran into a problem trying to crop an image between two points. In my project I have a pictureBox (named AP), and the general idea is that the user clicks on two points and the program crops the image between these two corners. I've tried two methods, one with Bitmap.Crop and the other one with Graphics.DrawImage, but both seemed to fail for the same reason and didn't work at all (cropped a much smaller portion of the image).
Code:
private void AP_Click(object sender, EventArgs e)
{
// Setting the corners
else if (mark_shape == 0)
{
var mouseEventArgs = e as MouseEventArgs;
if (picture_corners_set == 0)
{
northEast = AP.PointToClient(new Point(mouseEventArgs.X, mouseEventArgs.Y));
picture_corners_set = 1;
}
else if (picture_corners_set == 1)
{
southWest = AP.PointToClient(new Point(mouseEventArgs.X, mouseEventArgs.Y));
Rectangle imageRectangle = new Rectangle(southWest.X, northEast.Y, (northEast.X - southWest.X), (southWest.Y - northEast.Y));
var bmp = new Bitmap(imageRectangle.Width, imageRectangle.Height);
using (var gr = Graphics.FromImage(bmp))
{
gr.DrawImage(AP.Image, 0, 0, imageRectangle, GraphicsUnit.Pixel);
}
AP.Image = bmp;
enableAllButtons();
}
}
}
Since your cropped Bitmap image size is the same as the width/height of the user selection, I'm guessing you want that cropped image to be in the top/left of the new Bitmap and fill it. As it is, you're telling the DrawImage() method to draw that portion of the Bitmap in the same location, albeit in a smaller size Bitmap.
The correct way to do this is to draw the source rectangle image at (0, 0):
private Point pt1, pt2;
private void AP_Click(object sender, EventArgs e)
{
// ... obviously other code here ...
else if (mark_shape == 0) // Setting the corners
{
Point pt = AP.PointToClient(Cursor.Position);
if (picture_corners_set == 0)
{
pt1 = new Point(pt.X, pt.Y);
picture_corners_set = 1;
}
else if (picture_corners_set == 1)
{
pt2 = new Point(pt.X, pt.Y);
picture_corners_set = 0;
Rectangle imageRectangle = new Rectangle(new Point(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y)), new Size(Math.Abs(pt2.X - pt1.X) + 1, Math.Abs(pt2.Y - pt1.Y) + 1));
var bmp = new Bitmap(imageRectangle.Width, imageRectangle.Height);
using (var gr = Graphics.FromImage(bmp))
{
gr.DrawImage(AP.Image, 0, 0, imageRectangle, GraphicsUnit.Pixel);
}
AP.Image = bmp;
enableAllButtons();
}
}
}
There are several other overloads you could use to do this, but the one above makes it pretty clear that imageRectangle is being drawn at (0, 0).

C# PictureBox and 2x byte array of PNG [duplicate]

Simple idea: I have two images that I want to merge, one is 500x500 that is transparent in the middle the other one is 150x150.
Basic idea is this: Create an empty canvas that is 500x500, position the 150x150 image in the middle of the empty canvas and then copy the 500x500 image over so that the transparent middle of it allows the 150x150 to shine through.
I know how to do it in Java, PHP and Python... I just don't have any idea what objects/classes to use in C#, a quick example of copying an images into another would suffice.
basically i use this in one of our apps:
we want to overlay a playicon over a frame of a video:
Image playbutton;
try
{
playbutton = Image.FromFile(/*somekindofpath*/);
}
catch (Exception ex)
{
return;
}
Image frame;
try
{
frame = Image.FromFile(/*somekindofpath*/);
}
catch (Exception ex)
{
return;
}
using (frame)
{
using (var bitmap = new Bitmap(width, height))
{
using (var canvas = Graphics.FromImage(bitmap))
{
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.DrawImage(frame,
new Rectangle(0,
0,
width,
height),
new Rectangle(0,
0,
frame.Width,
frame.Height),
GraphicsUnit.Pixel);
canvas.DrawImage(playbutton,
(bitmap.Width / 2) - (playbutton.Width / 2),
(bitmap.Height / 2) - (playbutton.Height / 2));
canvas.Save();
}
try
{
bitmap.Save(/*somekindofpath*/,
System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception ex) { }
}
}
This will add an image to another.
using (Graphics grfx = Graphics.FromImage(image))
{
grfx.DrawImage(newImage, x, y)
}
Graphics is in the namespace System.Drawing
After all this, I found a new easier method try this ..
It can join multiple photos together:
public static System.Drawing.Bitmap CombineBitmap(string[] files)
{
//read all images into memory
List<System.Drawing.Bitmap> images = new List<System.Drawing.Bitmap>();
System.Drawing.Bitmap finalImage = null;
try
{
int width = 0;
int height = 0;
foreach (string image in files)
{
//create a Bitmap from the file and add it to the list
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(image);
//update the size of the final bitmap
width += bitmap.Width;
height = bitmap.Height > height ? bitmap.Height : height;
images.Add(bitmap);
}
//create a bitmap to hold the combined image
finalImage = new System.Drawing.Bitmap(width, height);
//get a graphics object from the image so we can draw on it
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(finalImage))
{
//set background color
g.Clear(System.Drawing.Color.Black);
//go through each image and draw it on the final image
int offset = 0;
foreach (System.Drawing.Bitmap image in images)
{
g.DrawImage(image,
new System.Drawing.Rectangle(offset, 0, image.Width, image.Height));
offset += image.Width;
}
}
return finalImage;
}
catch (Exception ex)
{
if (finalImage != null)
finalImage.Dispose();
throw ex;
}
finally
{
//clean up memory
foreach (System.Drawing.Bitmap image in images)
{
image.Dispose();
}
}
}

Image used by another process

I am getting a screenshot of the computer, then setting it as a picture box by copying it and then using it but after the first time it does it, it says the picture is being used by another process but im guessing i just dungoofed.
public void UpdatePic()
{
String newtemp = System.Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) + "\\screentemp.png";
if (File.Exists(newtemp)) { File.Delete(newtemp); }
File.Copy(screendirect, newtemp);
Image image = Image.FromFile(newtemp);
try
{
using (Bitmap tempBitmap = new Bitmap(image))
{
Size size = new Size(pictureBox1.Width, pictureBox1.Height);
Bitmap backgroundBitmap = new Bitmap(size.Width, size.Height);
using (Graphics g = Graphics.FromImage(backgroundBitmap))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Get the set of points that determine our rectangle for resizing.
Point[] corners = { new Point(0, 0), new Point(backgroundBitmap.Width, 0), new Point(0, backgroundBitmap.Height)};
g.DrawImage(tempBitmap, corners);
g.Dispose();
}
pictureBox1.Image = backgroundBitmap;
}
}
finally
{
}
}

Merge two images to create a single image in C#.Net

I have a requirement wherein I need to merge two different png/jpeg images resulting into a single image using C#.Net. There will be a particular location defined on the source image wherein I need to insert another image. Can anybody suggest some links ?
This method merge two images one in the top of the other you can modify the code to meet for your needs:
public static Bitmap MergeTwoImages(Image firstImage, Image secondImage)
{
if (firstImage == null)
{
throw new ArgumentNullException("firstImage");
}
if (secondImage == null)
{
throw new ArgumentNullException("secondImage");
}
int outputImageWidth = firstImage.Width > secondImage.Width ? firstImage.Width : secondImage.Width;
int outputImageHeight = firstImage.Height + secondImage.Height + 1;
Bitmap outputImage = new Bitmap(outputImageWidth, outputImageHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(outputImage))
{
graphics.DrawImage(firstImage, new Rectangle(new Point(), firstImage.Size),
new Rectangle(new Point(), firstImage.Size), GraphicsUnit.Pixel);
graphics.DrawImage(secondImage, new Rectangle(new Point(0, firstImage.Height + 1), secondImage.Size),
new Rectangle(new Point(), secondImage.Size), GraphicsUnit.Pixel);
}
return outputImage;
}
After all this, I found a new easier method try this ..
It can join multiple photos together:
public static System.Drawing.Bitmap CombineBitmap(string[] files)
{
//read all images into memory
List<System.Drawing.Bitmap> images = new List<System.Drawing.Bitmap>();
System.Drawing.Bitmap finalImage = null;
try
{
int width = 0;
int height = 0;
foreach (string image in files)
{
//create a Bitmap from the file and add it to the list
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(image);
//update the size of the final bitmap
width += bitmap.Width;
height = bitmap.Height > height ? bitmap.Height : height;
images.Add(bitmap);
}
//create a bitmap to hold the combined image
finalImage = new System.Drawing.Bitmap(width, height);
//get a graphics object from the image so we can draw on it
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(finalImage))
{
//set background color
g.Clear(System.Drawing.Color.Black);
//go through each image and draw it on the final image
int offset = 0;
foreach (System.Drawing.Bitmap image in images)
{
g.DrawImage(image,
new System.Drawing.Rectangle(offset, 0, image.Width, image.Height));
offset += image.Width;
}
}
return finalImage;
}
catch (Exception)
{
if (finalImage != null)
finalImage.Dispose();
//throw ex;
throw;
}
finally
{
//clean up memory
foreach (System.Drawing.Bitmap image in images)
{
image.Dispose();
}
}
}
Disclaimer: I work at Atalasoft
Our DotImage Photo SDK (which is free) can do this.
To open an image
AtalaImage botImage = new AtalaImage("bottomImage.png");
AtalaImage topImage = new AtalaImage("topImage.png");
To overlay one on top of another
Point pos = new Point(0,0); // or whatever you need
OverlayCommand cmd = new OverlayCommand(topImage, pos);
ImageResults res = cmd.Apply(botImage);
If you need the resulting image to be a different size, look at the CanvasCommand. You could also create an AtalaImage of the size you need, then overlay each image onto it.
To save
botImage.Save("newImage.png", new PngEncoder(), null);
String jpg1 = #"c:\images.jpeg";
String jpg2 = #"c:\images2.jpeg";
String jpg3 = #"c:\image3.jpg";
Image img1 = Image.FromFile(jpg1);
Image img2 = Image.FromFile(jpg2);
int width = img1.Width + img2.Width;
int height = Math.Max(img1.Height, img2.Height);
Bitmap img3 = new Bitmap(width, height);
Graphics g = Graphics.FromImage(img3);
g.Clear(Color.Black);
g.DrawImage(img1, new Point(0, 0));
g.DrawImage(img2, new Point(img1.Width, 0));
g.Dispose();
img1.Dispose();
img2.Dispose();
img3.Save(jpg3, System.Drawing.Imaging.ImageFormat.Jpeg);
img3.Dispose();
private void Merge _Click(object sender, EventArgs e)
{
}
DirectoryInfo directory=new DirectoryInfo("D:\\Images");
if(directory!=null)
{
FileInfo[]files = directory.GetFiles();
MergeImages(Image);
}
private void MergeImages(FileInfo[] Image)
{
//change the location to store the final image.
string FImage= #"D:\\Images\\FImage.jpg";
List imageHeights = new List();
int nIndex = 0;
int width = 0;
foreach (FileInfo file in files)
{
Image img = Image.FromFile(file.FullName);
imageHeights.Add(img.Height);
width += img.Width;
img.Dispose();
}
imageHeights.Sort();
int height = imageHeights[imageHeights.Count - 1];
Bitmap NewImg = new Bitmap(width, height);
Graphics Gr= Graphics.FromImage(NewImg);
Gr.Clear(SystemColors.AppWorkspace);
foreach (FileInfo file in files)
{
Image img = Image.FromFile(file.FullName);
if (nIndex == 0)
{
Gr.DrawImage(img, new Point(0, 0));
nIndex++;
width = img.Width;
}
else
{
Gr.DrawImage(img, new Point(width, 0));
width += img.Width;
}
img.Dispose();
}
Gr.Dispose();
NewImg .Save(FImage, System.Drawing.Imaging.ImageFormat.Jpeg);
NewImg .Dispose();
imageLocation.Image = Image.FromFile(FImage);
}

Categories

Resources