The thing I want to do is simple. I want to take a picture I already have and paste it into a blank graphics/picture at a certain point, thus expanding my picture's bounds.
To clarify :
private static Image PasteImage(Image startimage) //start image is a square of Size(30,30)
{
//Create a new picture/graphics with size of (900,900);
//Paste startimage inside the created picture/graphics at Point (400,450)
//Return the picture/graphics which should return a square within a square
}
private static Image PasteImage(Image startimage)
{
int width = Math.Max(900, 400 + startimage.Width);
int height = Math.Max(900, 450 + startimage.Height);
var bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp)) {
g.DrawImage(startimage, 400, 450);
}
return bmp;
}
It's better to get rid of constants in your code and add a couple of additional params:
private static Image PasteImage(Image startimage, Size size, Point startpoint)
{
int width = Math.Max(size.Width, startpoint.X + startimage.Width);
int height = Math.Max(size.Height, startpoint.Y + startimage.Height);
var bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp)) {
g.Clear(Color.Black);
g.DrawImage(startimage, new Rectangle(startpoint, startimage.Size));
}
return bmp;
}
Create an image from the startimage using the following
Graphics.FromImage(startimage);
Draw the image where you want to using
g.DrawImage(...)
Related
Trying to add a watermark image to a png image, i´ve been able to do it, but i want to take out the hardCoded size regulation for the rectangle of the waterMark, and make it always stay in the center of the image. How can i achieve this.
public Form1()
{
InitializeComponent();
picBox.Parent = this;
picBox.Dock = DockStyle.Fill;
picBox.SizeMode = PictureBoxSizeMode.Zoom;
Bitmap Jpg = new Bitmap(#"C:\Users\tferreira\Desktop\213123.PNG");
using (Bitmap Bmp = new Bitmap(#"C:\Users\tferreira\Desktop\logo.png"))
{
using (Bitmap WatermarkBmp = new Bitmap(Bmp, Bmp.Width / 1, Bmp.Height / 1))
{
picBox.Image = WatermarkImage(Jpg, WatermarkBmp, new Point(400, 100), 0.40F);
}
}
}
public Bitmap WatermarkImage(Bitmap ImageToWatermark, Bitmap Watermark, Point WatermarkPosition, float Opacity)
{
using (Graphics G = Graphics.FromImage(ImageToWatermark))
{
using (ImageAttributes IA = new ImageAttributes())
{
ColorMatrix CM = new ColorMatrix();
CM.Matrix33 = Opacity;
IA.SetColorMatrix(CM);
G.DrawImage(Watermark, new Rectangle(WatermarkPosition, Watermark.Size), 0, 0, Watermark.Width, Watermark.Height, GraphicsUnit.Pixel, IA);
}
}
return ImageToWatermark;
}
Right now the images are hardCoded but that will be taken out. If anyone can help me make this watermark allways stay centered i thank you.
I fixed this problem with this nice peace of code.
System.Drawing.Image img = System.Drawing.Image.FromFile(JpgFilePath);
Bitmap jpg = new Bitmap(img);
filePath = JpgFilePath;
int Width = jpg.Width;
int Height = jpg.Height;
jpg.SetResolution(300, 300);
WaterMarked = WatermarkImage(jpg, WaterMarkBit, new Point((Width - WaterMarkBit.Width) / 2, (Height - WaterMarkBit.Height) / 2), 0.4F);
WaterMarked.Save(filePath.Replace(".jpg", "") + ".tif", ImageFormat.Tiff);
filesJpgForTif.Add(JpgFilePath.Replace("jpg", "tif"));
Using the the sizes of the image and sizes of the watermark and divide it by 2 it makes the image always stay centered.
Good day
i don't know if my title is correct. sorry for my bad english
How to overlay two picturebox using c# inoder to achieve the image below, and change the opacity of upper picture box on runtime.
what i need to achieve is something like this. i have two images and i need to overlay them
first image:
enter image description here
and i have second image with a text of: Another Text on image.
and the location of the text is lower than the text location of the first image
(i can't upload more than two image because i don't have 10 reputation yet.)
i need to do like on the image below, but using two picturebox and can change the opacity in order for the second picturebox below the first one to be seen
and the output of the two image:
enter image description here
i created the output image using java. i know that i can run the jar file using c#. but the user required to changed the opacity on run time. so how can i do this?
this is the java code i used
BufferedImage biInner = ImageIO.read(inner);
BufferedImage biOutter = ImageIO.read(outter);
System.out.println(biInner);
System.out.println(biOutter);
Graphics2D g = biOutter.createGraphics();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
int x = (biOutter.getWidth() - biInner.getWidth()) / 2;
int y = (biOutter.getHeight() - biInner.getHeight()) / 2;
System.out.println(x + "x" + y);
g.drawImage(biInner, x, y, null);
g.dispose();
ImageIO.write(biOutter, "PNG", new File(output));
i hope my question is understandable. thank you
Here you go, just a sample, but blueBox is transparent (0.5):
public sealed partial class Form1 : Form
{
private readonly Bitmap m_BlueBox;
private readonly Bitmap m_YellowBox;
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
m_YellowBox = CreateBox(Color.Yellow);
m_BlueBox = CreateBox(Color.Blue);
m_BlueBox = ChangeOpacity(m_BlueBox, 0.5f);
}
public static Bitmap ChangeOpacity(Image img, float opacityvalue)
{
var bmp = new Bitmap(img.Width, img.Height);
using (var graphics = Graphics.FromImage(bmp))
{
var colormatrix = new ColorMatrix();
colormatrix.Matrix33 = opacityvalue;
var imgAttribute = new ImageAttributes();
imgAttribute.SetColorMatrix(colormatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
graphics.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, img.Width, img.Height,
GraphicsUnit.Pixel, imgAttribute);
}
return bmp;
}
private static Bitmap CreateBox(Color color)
{
var bmp = new Bitmap(200, 200);
for (var x = 0; x < bmp.Width; x++)
{
for (var y = 0; y < bmp.Height; y++)
{
bmp.SetPixel(x, y, color);
}
}
return bmp;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(m_YellowBox, new Point(10, 10));
e.Graphics.DrawImage(m_BlueBox, new Point(70, 70));
}
}
I need to fill an rectangle on bottom of my image, but not over the image, so it should be a kind of append a rectangle to bottom of image.
What I have for now:
private void DrawRectangle()
{
string imageFilePath = #"c:\Test.jpg";
Bitmap bitmap = (Bitmap)Image.FromFile(imageFilePath);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
using (Image img = Image.FromFile(imageFilePath))
{
SolidBrush brush = new SolidBrush(Color.Black);
int width = img.Width;
int height = img.Height - 350;
graphics.FillRectangle(brush, 0, height, width, 350);
}
}
bitmap.Save(#"c:\Test1.jpg");
}
But this is over the image.
Any idea's?
Thank you.
You need to know the dimensions of your original image in order to set the size of the new bitmap, which must be larger to accommodate the rectangle.
private void DrawRectangle()
{
string imageFilePath = #"c:\Test.jpg";
int rectHeight = 100;
using (Image img = Image.FromFile(imageFilePath)) // load original image
using (Bitmap bitmap = new Bitmap(img.Width, img.Height + rectHeight)) // create blank bitmap of desired size
using (Graphics graphics = Graphics.FromImage(bitmap))
{
// draw existing image onto new blank bitmap
graphics.DrawImage(img, 0, 0, img.Width, img.Height);
SolidBrush brush = new SolidBrush(Color.Black);
// draw your rectangle below the original image
graphics.FillRectangle(brush, 0, img.Height, img.Width, rectHeight);
bitmap.Save(#"c:\Test1.bmp");
}
}
take a look at the FillRectangle() method overloads.. it has one with the following definition: FillRectangle(Brush brush, int PositionX, int PositionY, int Width, int Height)
your problem most likely stems on using an improper overload for what you're doing.
I have two Bitmaps, named largeBmp and smallBmp. I want to draw smallBmp onto largeBmp, then draw the result onto the screen. SmallBmp's white pixels should be transparent. Here is the code I'm using:
public Bitmap Superimpose(Bitmap largeBmp, Bitmap smallBmp) {
Graphics g = Graphics.FromImage(largeBmp);
g.CompositingMode = CompositingMode.SourceCopy;
smallBmp.MakeTransparent();
int margin = 5;
int x = largeBmp.Width - smallBmp.Width - margin;
int y = largeBmp.Height - smallBmp.Height - margin;
g.DrawImage(smallBmp, new Point(x, y));
return largeBmp;
}
The problem is that the result winds up transparent wherever smallBmp was transparent! I just want to see through to largeBmp, not to what's behind it.
CompositingMode.SourceCopy is the problem here. You want CompositingMode.SourceOver to get alpha blending.
Specify the transparency color of your small bitmap. e.g.
Bitmap largeImage = new Bitmap();
Bitmap smallImage = new Bitmap();
--> smallImage.MakeTransparent(Color.White);
Graphics g = Graphics.FromImage(largeImage);
g.DrawImage(smallImage, new Point(10,10);
Winform copy image on top of another
private void timerFFTp_Tick(object sender, EventArgs e)
{
if (drawBitmap)
{
Bitmap bitmap = new Bitmap(_fftControl.Width, _fftControl.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
_fftControl.DrawToBitmap(bitmap, new Rectangle(0, 0, _fftControl.Width, _fftControl.Height));
if (!fDraw)
{
bitmap.MakeTransparent();
Bitmap fftFormBitmap = new Bitmap(_fftForm.BackgroundImage);
Graphics g = Graphics.FromImage(fftFormBitmap);
g.DrawImage(bitmap, 0, 0);
_fftForm.BackgroundImage = fftFormBitmap;
}
else
{
fDraw = false;
_fftForm.Width = bitmap.Width + 16;
_fftForm.Height = bitmap.Height + 48;
_fftForm.BackgroundImage = bitmap;
}
}
}
Whats going on is i need to draw a black rectangle over the image. I have to load a tif and then show a blackbox over it. I was helped with some code but i continously got the error: A Graphics object cannot be created from an image that has an indexed pixel format.
So i had to read it in to bit format, but when i display the box it resizes the box wierd. And completly displays the the picture box in all black nothing of the original image. if someone could help me where i'm going wrong that would be awesome.
Bitmap original = (Bitmap)System.Drawing.Image.FromFile(coveted, true);
Bitmap newImage = new Bitmap(original.Width, original.Height);
pictureBox1.Image = newImage;
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
using (SolidBrush brush = new SolidBrush(Color.Black))
{
g.FillRectangle(brush, new Rectangle(x1value, y1value, x3value, y3value));
}
}
I'm not sure how I can make this clearer. Whats happening is I have a tif in a unsupported format. So I have to change it to a Bitmap so I can actually draw a rectangle on it. Then I need to display this redacted image (the original with the redaction) in a picturebox. Whats going on with the code above, is once it's completed, all it displays is a blackbox with no original image.
I believe i ran something about using a Bitmap from stream and then closing the stream. Anybody familiar with this?
Thanks to all the help from STO members!! heres the correct code for redacting images if you encounter the error "A Graphics object cannot be created from an image that has an indexed pixel format.".
if you're given the redacted starting points (obviously you have to make the Regex work to your situation):
//Regex for pulling points from a file
string x1 = x1 = Regex.Match(l, #"\r\n(\d+)\r\n(\d+)").Groups[2].Value;
string y1 = y1 = Regex.Match(l, #"\r\n(\d+)\r\n(\d+)\r\n(\d+)").Groups[3].Value;
string x2 = x2 = Regex.Match(l, #"\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)").Groups[4].Value;
string y2 = y2 = Regex.Match(l, #"\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)").Groups[5].Value;
string x3 = x3 = Regex.Match(l, #"\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)").Groups[6].Value;
string y3 = y3 = Regex.Match(l, #"\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)\r\n(\d+)").Groups[7].Value;
{
//convert string to int for redacted points
int x1value = Convert.ToInt32(x1);
int y1value = Convert.ToInt32(y1);
int x3value = Convert.ToInt32(x3);
int y3value = Convert.ToInt32(y3);
{
//BEGIN Workaround for indexed pixels
Bitmap original = (Bitmap)System.Drawing.Image.FromFile(YOURFILE, true);
Bitmap newImage = new Bitmap(original);
pictureBox1.Image = newImage; //END Workaround for indexed pixels
using (Graphics g = Graphics.FromImage(pictureBox1.Image)) //start redaction
{
using (SolidBrush brush = new SolidBrush(Color.Black))
{
g.DrawImageUnscaled(newImage, 0,0);
g.FillRectangle(brush, new Rectangle(x1value, y1value, x3value, y3value));
}
} //End Redaction
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; //Resized to fit into a static picturebox
}
}
Instead of
Bitmap newImage = new Bitmap(original.Width, original.Height);
you want
Bitmap newImage = new Bitmap(original);
This will make your newImage start with the contents of original.
The difference will be that you will end up with newImage.PixelFormat == PixelFormat.Format32bppArgb, while I'm assuming original.PixelFormat == PixelFormat.Format1bppIndexed.
With PixelFormat.Format32bppArgb, you can create a Graphics object; you cannot with PixelFormat.Format1bppIndexed.
This should work for you:
original = (Bitmap)System.Drawing.Image.FromFile(coveted, true);
using (Graphics g = Graphics.FromImage(original))
{
using (SolidBrush brush = new SolidBrush(Color.Black))
{
g.FillRectangle(brush, new Rectangle(x1value, y1value, x3value, y3value));
}
}
pictureBox1.Image = original;
You aren't drawing the original image on the newImage.
To do so :
g.DrawImageUnscaled(original, 0, 0);
Also, I would do it as follows, I think it works better drawing in RAM, and then showing it to screen. Perhaps I'm wrong though.
using (Graphics g = Graphics.FromImage(newImage))
{
g.DrawImageUnscaled(original, 0, 0);
using (SolidBrush brush = new SolidBrush(Color.Black))
{
g.FillRectangle(brush, new Rectangle(x1value, y1value, x3value, y3value));
}
}
pictureBox1.Image = newImage;
I haven't tested the code above.. good luck though.