I tried to save pictureboxe and picture box in layers
Below is the placement of the current form
Try Method 1
public Form1()
{
InitializeComponent();
pictureBox1.Controls.Add(pictureBox2);
pictureBox2.Location = new Point(0, 0);
pictureBox2.BackColor = Color.Transparent;
}
private void button1_Click(object sender, EventArgs e)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
pictureBox1.Image.Save(path+"\\image.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
}
Overlay picturebox2 on picturebox1
Try Method 2
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawImage(this.imageList1.Images[0], 50, 50,393,336);
}
private void button1_Click(object sender, EventArgs e)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
pictureBox1.Image.Save(path+"\\image.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
}
Redraw in picturebox1
I want the two images to be perfectly overlapped and saved. Is there a solution?
As I understand it, you want to draw picture box in layers similar to the popular editing app. We'll make our own version and call it PictureShop. As Jimi commented, you need only one PictureBox
and when you want to draw on it, call its Refresh
method. It responds by firing a Paint
message and providing a Graphics
canvas to draw on. So, if we have put the images in a Layers
list of bitmaps, we can draw the layers on top of one another. Obviously there is a problem doing this, but it's a start.
/// <summary>
/// Add layer, then refresh PictureBox to draw.
/// </summary>
private void onButtonDrawClick(object? sender, EventArgs e)
{
switch ( _clickCount++ )
{
case 0:
Layers.Add((Bitmap)Bitmap.FromFile(Path.Combine(ImageFolder, "Image1.png")));
break;
case 1:
Layers.Add((Bitmap)Bitmap.FromFile(Path.Combine(ImageFolder, "Image2.png")));
break;
}
pictureBox1.Refresh();
}
private List<Bitmap> Layers { get; } = new List<Bitmap>();
private void onPicturebox1Paint(object? sender, PaintEventArgs e)
{
foreach (var bmp in Layers)
{
e.Graphics.DrawImage(bmp, pictureBox1.ClientRectangle);
}
}
If we were using that "other" app, we would go to the top layer and probably use a magic wand to select around the top image, and make it transparent. To make PictureShop do something similar, have it replace pixels in the top image if the color falls within a range of values.
Now the Tolerance slider lets you adjust the amount or transparency before saving.
Transparency method
private Bitmap replaceColor(Bitmap bmp, Color targetColor, int tolerance)
{
if(tolerance == 0) return bmp;
var copy = new Bitmap(bmp);
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < copy.Height; y++)
{
Color pixelColor = copy.GetPixel(x, y);
if (localIsWithinTolerance(pixelColor, targetColor, tolerance))
{
copy.SetPixel(x, y, Color.Transparent);
}
}
}
bool localIsWithinTolerance(Color pixelColor, Color targetColor, int tolerance)
{
return Math.Abs(pixelColor.R - targetColor.R) <= tolerance &&
Math.Abs(pixelColor.G - targetColor.G) <= tolerance &&
Math.Abs(pixelColor.B - targetColor.B) <= tolerance;
}
return copy;
}
New paint method
private void onPicturebox1Paint(object? sender, PaintEventArgs e)
{
Bitmap bmp;
for (int i = 0; i < Layers.Count; i++)
{
switch (i)
{
case 0:
bmp = Layers[i];
break;
case 1:
bmp = replaceColor(Layers[i], Color.FromArgb(0xF0, 0xF0, 0xF0), trackBarTolerance.Value);
break;
default:
return;
}
e.Graphics.DrawImage(bmp, pictureBox1.ClientRectangle);
}
}