Convert a Resource Image into Image Brush - c# - c#

i want to change in runtime the Background property and i have to set an ImageBrush for it.
I have added some images as Resources on my project, and now i can use them as System.Drawing.Bitmap.
How can i convert System.Drawing.Bitmap into ImageBrush ?

If you are using the codebehind to set it, you can do it like this:
BitmapImage img;
// get bitmapimage from resources and assign to img
ImageBrush brush = new ImageBrush();
brush.ImageSource = img;
myControl.Background = brush;
If you are using databinding you'd need to implement a ValueConverter

From How to create ImageBrush from System.Drawing.Image in WPF?:
var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions()
);
bitmap.Dispose();
var brush = new ImageBrush(bitmapSource);
"This solution, however, doesnt free the memory of the handle. For information on how to remove the memory leak see WPF CreateBitmapSourceFromHBitmap() memory leak"

Related

C# WPF rendering true monochromatic image from ink canvas

I am loading an image into an ink canvas, the input image is always monochromatic, I am then drawing on that image with a white pen and intending to save it.
When the image is loaded some of the pre-existing lines which I know to be 1 pixel thick have an edge added to them which isn't monochromatic.
The way I have though to fix this is by rendering the bitmap and then discarding all pixels with a value of less than 255.
I have tried to use the pixel format BlackWhite, however this generates the error:
An unhandled exception of type 'System.ArgumentException' occurred in PresentationCore.dll
Additional information: 'BlackWhite' PixelFormat is not supported for this operation.
The line of code rendering the bitmap
RenderTargetBitmap rtb = new RenderTargetBitmap((int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight, 96, 96, System.Windows.Media.PixelFormats.BlackWhite);
I'm not sure if the issue lies in how I loaded it into the ink canvas so that code is also included below
private void LoadImagetoCanvas(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();
Nullable<bool> result = openFileDlg.ShowDialog();
if (result == true)
{
global.canvas1filepath = openFileDlg.FileName;
System.Windows.Controls.Image myImage = new System.Windows.Controls.Image();
myImage.Source = new BitmapImage(new Uri(global.canvas1filepath));
BitmapImage bmp = new BitmapImage(new Uri(global.canvas1filepath, UriKind.Absolute));
global.canvas1imagexpixels = (int)bmp.Width;
global.canvas1imageypixels = (int)bmp.Height;
ImageBrush canvas1Background = new ImageBrush();
canvas1Background.ImageSource = new BitmapImage(new Uri(global.canvas1filepath, UriKind.Relative));
inkCanvas1.Background = canvas1Background;
}
}
I'll compile an answer here - thanks to Sinatr & Clemens for their help with the theory and examples
The solution is based in the XMAL code for the ink canvas i'm using, I found adding the two following properties removed any edges to the 1 pixel wide lines I was drawing:
RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.EdgeMode="Aliased"

WPF: programatically draw a Rectangle to an ImageSource instance

I am new to C# and to WPF, and I could be looking at this completely wrong. I have a JPEG byte array as a source. I cannot change this. I need to get the array, perform some calculations and draw rectangles in areas of the JPEG. I then write it to an Image XAML control.
I get the JPEG and I can convert it into an ImageSource and display it to an ImageControl. I can't find a way to get the drawing context from the ImageSource. I use ImageSourceConverter to read in the JPEG array and this class returns an ImageSource instance, duh!.
ImageSource mImage = (ImageSource)mConverter.ConvertFrom(mImageBuffer);
ImageSource does not have a drawing context property.
What it seems like I need is a DrawingImage, it is derived from ImageSource and has a drawing context property.
How can I use a DrawingImage instead of the ImageSource.
I looked at the ImageDrawing class, it has an ImageSource property. This class doesn't have a drawing context.
I am currently looking into the Visual class, and help where to look would be appreciated.
Edit:
Thanks #nefarious for pointing me in the right direction. I ended with the following:
ImageSource mImage = (ImageSource)mConverter.ConvertFrom(mImageBuffer);
BitmapSource bImage = mImage as BitmapSource;
// Draw a Rectangle
DrawingVisual dVisual = new DrawingVisual();
using (DrawingContext dc = dVisual.RenderOpen())
{
dc.DrawImage(bImage, new Rect(0, 0, bImage.PixelWidth, bImage.PixelHeight));
dc.DrawRectangle(Brushes.Green, null, new Rect(20, 20, 150, 100));
}
RenderTargetBitmap targetBitmap = new RenderTargetBitmap(640,480,96,96, PixelFormats.Default);
targetBitmap.Render(dVisual);
WriteableBitmap wBitmap = new WriteableBitmap(targetBitmap);
image.Source = wBitmap;
Have you looked at using Visuals, I don't know how efficient they are but it seems that you will be unable to copy the source into an ImageSource and draw directly into it.
Create a DrawingVisual and draw the ImageSource and the Rectangles into the drawing context of the drawing visual.
Then use WriteableBitmap to show it in the image;

WPF animated GIF Source change on runtime .. but remains static on source change

Hi guys please help with this ...
What exactly i am trying to do is .. changing the ANIMATED GIF IMAGE SOURCE on runtime.
However the image change is happening but as the image is animated its getting blacked out somehow may be the thread is busy !
Here's the code !
var image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(#"/BackgroundWorkerWpf;component/Media/p1.gif", UriKind.Relative);
image.EndInit();
ImageBehavior.SetAnimatedSource(img, image);
The image source is changed as per required but the image remains static just like its a snap of the original GIF Image.THANKS IN ADVANCE :)
PS : I AM USING THE REFERENCE LIB FROM CODEPLEX
After you changed property animated source you should invoke ImageBehavior.SetRepeatBehavior method.
Try following code:
var image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(#"/BackgroundWorkerWpf;component/Media/p1.gif", UriKind.Relative);
image.EndInit();
ImageBehavior.SetAnimatedSource(img, image);
ImageBehavior.SetRepeatBehavior(img, new RepeatBehavior(0));
ImageBehavior.SetRepeatBehavior(img, RepeatBehavior.Forever);

Create WriteableBitmap from UIControl WPF

I am currently converting a Silverlight application into WPF. In my silverlight application I have the code
WriteableBitmap sceneBitmap = new WriteableBitmap(scene, new TranslateTransform() { Y = 10 });
WriteableBitmap newone = TimelineMainHelper.CropImage(sceneBitmap, 0, 0, sceneBitmap.PixelWidth, sceneBitmap.PixelHeight - 25);
newone.Invalidate();
img.Source = newone;
Where scene is a control.
When putting this into WPF there are no overloads for the writeablebitmap class which take UIElement and Transform as the parameters. Firstly I was wondering why this is? and secondly I was wondering if there was a way getting a control to a writeablebitmap
Instead you will want to use RenderTargetBitmap and CroppedBitmap I believe:
RenderTargetBitmap rtb = new RenderTargetBitmap((int)scene.ActualWidth, (int)scene.ActualHeight, 96, 96, System.Windows.Media.PixelFormats.Pbgra32);
rtb.Render(this.sceneBitmap);
CroppedBitmap crop = new CroppedBitmap(sceneBitmap, new Int32Rect(0, 0, (int)sceneBitmap.ActualWidth, (int)sceneBitmap.ActualHeight));
Then you can do something like:
System.Windows.Controls.Image img = new Image();
img.Source = crop;
And go from there.
Disclaimer:
You may need to use different overloads and what not to do exactly what you wish. I just took a shot guessing what parameters to pass given your snippet.

Get ImageSource from Bitmap?

I want to set a background image for my form/window like this guy but instead of an image file on disk I've got a System.Drawing.Bitmap in memory.
I need to do something like this:
this.Background = new ImageBrush(new BitmapImage(bmp));
Except BitmapImage won't take a Bitmap, nor will ImageBrush and I'm not sure if any of the others will. There's one called BitmapCacheBrush but I don't know what that does.
Nevermind, I figured it out.
public static Brush CreateBrushFromBitmap(Bitmap bmp)
{
return new ImageBrush(Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()));
}
credit

Categories

Resources