How to overlap images and store them in new image objects - c#

I have two images,now i want to overlay the images,such that the other image appears on center or left corner of the other image,and then when finally both the images are overlayed i can store it in another new image object,and i want to all this in code behind only not xaml,how to do this?
if (((Grid)sender).Children.Count > 0)
{
gridBackground = (ImageBrush)(((Grid)sender).Background);
gridBackImage = new System.Windows.Controls.Image();
gridBackImage.Source = gridBackground.ImageSource;
}
System.Windows.Controls.Image imgRejectIcon;
if (((Grid)sender).Children.Count > 0)
{
imgRejectIcon = (System.Windows.Controls.Image)(((Grid)sender).Children[0]);
}
Now i want to merge gridBackImage and imgRejection and store it in new image object

You can arrange your two Images in any way that you want and I'll leave that code for you to do (it'd much simpler to do in XAML). In WPF, all UI controls extend the Visual class. This is very useful for making BitmapImages from UI controls, when used with the RenderTargetBitmap.Render method.
First, arrange your two Image controls into a Grid, or other container control, and then you can pass the container control to the RenderTargetBitmap.Render method and create an Image something like this:
RenderTargetBitmap renderTargetBitmap =
new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(yourContainerControl);
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (Stream fileStream = File.Create(filePath))
{
pngImage.Save(fileStream);
}

Related

Render to jpg/png WPF controls and WindowsFormHost containing WinForms controls

I have a WPF form that contains a WindowsFormsHost control.
This WindowsFormsHost control is added intentionally to add ActiveX/WinForms controls at the same time.
Eventually, I have to take a picture of the form that contains the WindowsFormsHost control, here is the problem.
I've found how to save wpf ( this way ) as jpg and winforms as jpg ( here ) too.
From WPF:
formGrid is base Grid in WPF form
RenderTargetBitmap rtb = new RenderTargetBitmap((int)formGrid.ActualWidth, (int)formGrid.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(formGrid);
JpegBitmapEncoder jpg = new JpegBitmapEncoder();
jpg.Frames.Add(BitmapFrame.Create(rtb));
using (Stream stm = File.Create(#"c:\testwpf.jpg"))
{
jpg.Save(stm);
}
From WinForms:
formhost is WindowsFormHost control
using (var bmp = new System.Drawing.Bitmap((int)formhost.Width, (int)formhost.Height))
{
formhost.Panel.DrawToBitmap(bmp, new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save(#"c:\testwinform.jpg")
}
What I want is to mix/merge, if it were possible, the result of getting both renderings into one single image.
PD: I tried to create a BitmapSource from Bitmap and add it to the JpegBitmapEncoder but I got no successful result.

ScreenShot in WPF

I am having two control image view and canvas.
Over image i am drawing rectangle.While taking screenshot i am only getting image not the rectangle.
Using below code i am getting black image
int Width = (int)canvas1.RenderSize.Width;
int Height = (int)canvas1.RenderSize.Height;
RenderTargetBitmap renderTargetBitmap =
new RenderTargetBitmap(Width, Height, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(canvas1);
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (Stream fileStream = File.Create(filePath))
{
pngImage.Save(fileStream);
}
if i am replacing canvas with image only image is coming.
How to take screenshot containing both the controls ?
have a no-op after the render call for the render to be completed before taking the screenshot.
Also am assuming you are able to view the drawn rectangle in the viewport
and it is only not appearing in the screenshot. If not make sure the color of the rectangle is distinct against the image background.
renderTargetBitmap.Render(canvas1);
//no-op for rendering to complete before taking screenshot.
_dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { }));
//screenshot code here.

Draw a bitmap in WPF

I am trying to draw some string to bitmap at certain position and copy a barcode bitmap to the new bitmap.I have not done with graphics before so i don't know where to start.
Can anyone guide me on this?my output of the bitmap is a receipt like.
Here is a solution. Please make a grid or canvas and put the barcode image and use a label with desired text and put the label on desired location relative to barcode grid. So, trick is you can immediately take screenshot of this grid using following code.Then, you are done.
public void ConvertToBitmapSource(UIElement element)
{
var target = new RenderTargetBitmap(
(int)element.RenderSize.Width, (int)element.RenderSize.Height,
96, 96, PixelFormats.Pbgra32);
target.Render(element);
var encoder = new PngBitmapEncoder();
var outputFrame = BitmapFrame.Create(target);
encoder.Frames.Add(outputFrame);
using (var file = File.OpenWrite("TestImage.png"))
{
encoder.Save(file);
}
}

How to save Canvas-Control at specific position (in a viewbox) to a png in c# wpf?

I want to develope a .NET application with WPF.
In the end there should be a Viewbox or something similar, this Viewbox should contain a canvas and in this canvas there could be various things like filled rectangles, ellipses etc. ( like a drawing application eg. paint).
Now I want to implement the functionallity to save the content of the Canvas to a PNG. I tried rendering the Canvas to a RenderTargetBitmap and then saving it.
The problem here is that I am not able to set specific coordinates, the only thing I can set is the Size (Canvas width & height) of the RenderTargetBitmap, but it will start rendering the Size starting from (0|0) where my Canvas element starts somewhere else. Is there some work arround for that??
The next Problem is, there should be the posibilty to add pictures as sub-element of the root-Canvas, but how could I care about quality and that everything in the Viewbox is printed?
Thank you very much!
------ EDIT ------
I think I've got a Solution:
void SaveUsingEncoder(Canvas myCanvas, string fileName)
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
RenderTargetBitmap bitmap = new RenderTargetBitmap(
(int)myCanvas.ActualWidth,
(int)myCanvas.ActualHeight,
96,
96,
PixelFormats.Pbgra32);
Rect bounds = VisualTreeHelper.GetDescendantBounds(myCanvas);
Console.WriteLine(bounds.X + "|" + bounds.Y + " " + bounds.Width + "|" + bounds.Height);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext ctx = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush(myCanvas);
ctx.DrawRectangle(vb, null, new Rect(bounds.Location, bounds.Size));
}
bitmap.Render(dv);
BitmapFrame frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = File.Create(fileName))
{
encoder.Save(stream);
}
}
This saves the complete canvas for me
at specific position -
I think in your case use Margins.

How to merge layers and save as an image in WPF?

I have two layers. The first layer is Image control. The source of it is Bitmap Image. And this is the background layer. The second one, which is the front layer is a canvas on which I can draw geometry objects (such as line, polyline, rectangle etc.) and the background of canvas is transparent.
How can I merge these two layers and save it as an image using WPF.
What do you mean by "Layers"? Just two controls sat in the same cell of a grid? If you have both "layers" sat in another container (such as a grid, or even the window) then you can use RenderTargetBitmap with that container to get your image. I have some details, an extension method for taking WPF "Screenshots" on my blog.
You can get bitmap of your parent panel on which you have placed your image control and canvas.
How is the code to get the bitmap of UIElement in WPF.
RenderTargetBitmap bmp = new RenderTargetBitmap(Width, Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(parentPanel);
Use something like, call this method from your canvas (this is canvas) -
private Bitmap ImageGenerator()
{
var transform = this.LayoutTransform;
// Call UpdateLayout to make sure changes all changes
// while drawing objects on canvas are reflected
var layer = AdornerLayer.GetAdornerLayer(this);
layer?.UpdateLayout();
// Get the size of canvas
var size = new System.Windows.Size(this.ActualWidth, this.ActualHeight);
// Measure and arrange the surface
// VERY IMPORTANT
this.Measure(size);
this.Arrange(new Rect(RenderSize));
RenderTargetBitmap renderBitmap =
new RenderTargetBitmap(
(int)this.ActualWidth,
(int)this.ActualHeight,
96d,
96d,
PixelFormats.Pbgra32);
renderBitmap.Render(this);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
// push the rendered bitmap to it
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
var stream = new MemoryStream();
encoder.Save(stream);
this.LayoutTransform = transform;
return new Bitmap(stream);
}

Categories