Performance of BitmapImage vs. ImageBrush - c#

I tried searching around but I couldn't find an answer to this question: are there performance improvements in using an ImageBrush to fill a rectangle rather than creating a BitmapImage and setting its source property?
I have to render an high number of images (we are trying to push over 5000), and for now I'm creating them this way:
<Image x:Name="img" RenderOptions.BitmapScalingMode="LowQuality"
Source="{Binding Path, Converter={StaticResource StringToImageConverter}, ConverterParameter={StaticResource string}}" >
</ext:IdImage>
and in the converter:
System.Windows.Media.Imaging.BitmapImage image = new System.Windows.Media.Imaging.BitmapImage();
image.BeginInit();
image.UriSource = new Uri(value as String);
image.DecodePixelWidth = int.Parse((String)parameter);
image.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad;
image.EndInit();
return image;
NB: I have to use the converter to set the DecodePixelWidth property.
Using an ImageBrush I could freeze the brush thus, according to what I read, increasing the performance so I was wondering if I should change the way I build the images.
P.S. The Images are not static but are translated around.

I think that the problem is not in the code but in the architecture WPF.
If your problem is performance, for my personal experience developing XAML is necessary that the pc is preferably provided with a dedicated video card. However, many times even in very old pc with windows XP to thin the program I did install the updates direct X library
http://support.microsoft.com/kb/179113/en
XAML is based on directX
Try it and let me know

Related

How to combine png images in Windows UWP app - preserving transparency?

Does anyone know the solution to layering PNG images for windows UWP app?
While preserving the transparency?
(this solution does not work in UWP application)
Merge two png images with transparency and retain transparency
End goal is to merge the PNG files to an Image object so it can be added to a Grid control.
One possible solution is using Blit method in WriteableBitmapEx. This method copies (blits) the pixels from the WriteableBitmap source to the destination WriteableBitmap (this) and following is a simple sample.
var writeableBmp = new WriteableBitmap(1, 1);
var image1 = await writeableBmp.FromContent(new Uri("ms-appx:///Assets/image1.png"));
var image2 = await writeableBmp.FromContent(new Uri("ms-appx:///Assets/image2.png"));
image1.Blit(new Rect(0, 0, image1.PixelWidth, image1.PixelHeight), image2, new Rect(0, 0, image2.PixelWidth, image2.PixelHeight));
//BlendedImage is a Image control in XAML
BlendedImage.Source = image1;
I think you may use the two image control in Grid in Xaml and both have bind the transparency in viewModel.But I see the link and I also can't use it.May MS change the API.I also interesting in this.
Lumia Imaging SDK doing just what you want. It can blend 2 ore more images together.
You can find sample code here

Fast way of loading high resolution image

had a project called Time Lapse Viewer which opens a folder with thousands of images and animates them using Timer.
The application is written in XAML by teh way and the code below is what I used to load the image.
bi = new BitmapImage();
bi.BeginInit();
bi.DecodePixelWidth = 720;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.UriSource = new Uri(this.ImageFilenames[this._image_index]);
bi.EndInit();
this.imgImage.Source = bi;
The images being loaded are from the DSLR and these images has 1536x2034 resolution and about 1.30+MB of size.
The code above is already fast enough to load the image in 720p but there are some noticable lag. I understand that when the image gets loaded for the first time, it requires some bit of time.
Is there anymore faster way to load an image other than loading them as a thumbnail?
Thanks.
You can load ina separate thread (BiatmapImage CAN be accessed from another thread when it is frozen - call Freeze after loading).
You can do that in multiple threads
But that is it. This is why most systems prepare thumbnails and store them in a separate file for repeated use.

Nearest-neighbor image sampling in 3D WPF

I'm desperately trying to render images onto a 3D surface in WPF using nearest-neighbor sampling. Below is an example of what I currently have, in all its blurriness. The ImageBrush is given a 64x64 texture.
I've tried decorating the XAML with RenderOptions.BitmapScalingMode="NearestNeighbor" everywhere from the Window to the ImageBrush without fortune. I've tried writing a custom pixel shader, and couldn't get a satisfactory result. It even appears that I cannot set the texture sampler's filtering mode from within the shader code. I've considered work-arounds, such as scaling up the source texture myself, but this would still leave artifacts at two of the edges where it begins interpolating into the next pixel.
Bottom line: Is there any way I can accomplish the effect of nearest neighbor image sampling on a 3D model in WPF?
Just had the same problem, the answer in this thread provides a workaround.
You can use a VisualBrush with an Image then WPF will respect the BitmapScalingMode on the image. You can also set the CachingHint (also on RenderOptions) which might improve performance (did not measure it though).
var image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/image.png")) };
RenderOptions.SetCachingHint(image, CachingHint.Cache);
RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);
var material = new DiffuseMaterial(new VisualBrush(image));
That works for simple scenes, as I said I didn't measure the performance, but I imagine the VisualBrush will hurt for bigger stuff (compared to an ImageBrush). Personally I'll switch over to Direct3D interop and render the scene via SharpDX when I hit that problem.

Render control into image in WinRT metro

I'm creating an application for windows 8 metro, I need to render a framework control into an image and save it to hard disk but do not know how. Can I use SharpDX for this? How can I do? Thanks in advance for the help
justin.m.chase's approach certainly works if you do not mind adding dependencies to SharpDX assemblies. The RenderTargetBitmap class might be a good fit for what you are trying to accomplish.
// Render XAML to bitmap
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(elementToRender);
// get the pixels
IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
// write the pixels to a InMemoryRandomAccessStream
var stream = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
stream.Seek(0);
If you follow through this thread the limitations of Metro and the reasons why it won't work are explained. The essence of it is:
Sorry, but rendering Xaml to an element or capturing a screenshot of
your own app did not make it into the release version. It is by design
that an app cannot capturing a screenshot of another app.
A workaround mentioned is:
What I meant was - you can draw shapes, text and images using
Direct2D. The same shapes that you would otherwise draw with XAML UI.
I did not mean to imply that you can render XAML controls - just that
you can use Direct2D as an alternative to achieve same results albeit
with somewhat more effort.
I apologize that this is not possible. The WritableBitmap class' Render() method is current insufficient to accomplish what you are wanting. For the same reason a screenshot cannot be created at this time. But these are the things that are on the backlog! But, now you know.
Because I think this is a more correct answer I would like to reiterate the comment that Zeeshan made in the original question.
There is a extension method for that in winrt xaml toolkit.
http://winrtxamltoolkit.codeplex.com/.../WriteableBitmapRenderExtensions.cs
Install via nuget:
> Install-Package WinRTXamlToolkit.Composition
Add the using:
using WinRTXamlToolkit.Composition;
Render your xaml:
var bitmap = await element.Render();

Tile based map editor: Scrolling: Generating new Image's while doing so locks up the application for some time

I'm currently working on a tile based map editor, focusing to get scrolling working exactly how I want. That's where I experience some troubles. While scrolling, images get generated to display the new content as you scroll around. This works fine till about 200 images (System.Windows.Controls.Image) being generated at a new side (simple maps, not complicated).
Whenever about 1000 images (or a lot more if you scroll faster..) get generated on the side, the application will hang for some time, depending on how rapid you scroll etc.
The cause of this temporarily hangup is always caused by this line. Removing this line eliminates the "lag" fully (but obviously does not give the wanted result):
img.Source = it.GetFullSpriteSource(0);
That method generates an ImageSource, or returns the ImageSource stored in a variable if already generated. The problem lies not in this method, since the following scenario gives the same problem.
public static ImageSource yellowimg;
[...]
System.Drawing.Bitmap derp = new System.Drawing.Bitmap(32, 32);
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(derp))
g.FillRectangle(System.Drawing.Brushes.Yellow, 0, 0, 32, 32);
yellowimg = Utilities.ToImgSource(derp);
[...]
img.Source = yellowimg;
So the problem probably lies in the fact I assign the ImageSource.
I am generating an ImageSource out of a Bitmap like this, might be relevant:
public static ImageSource ToImgSource(Bitmap bitmap)
{
return Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
I have also tried generation in a seperate Thread (background generation), but this results in the following error, trying to read the ImageSource from another thread.
The calling thread cannot access the object because different thread owns it
What are things I could try?
Keep in mind I'm not advanced with WPF (Recently started) and I have barely any knowledge about ImageSource.
Thanks,
~ Tgys
Instead of creating an ImageSource from a System.Drawing.Bitmap you should use WriteableBitmap. If you have to draw complicated drawing into the bitmap, you would have to draw into the DrawingContext of a DrawingVisual and render that DrawingVisual into a RenderTargetBitmap,
When you create ImageSource objects in a separate thread, you have to call their Freeze method before using them in the UI.

Categories

Resources