SoftwareBitmap compared to BitmapImage - c#

So I'm creating a UWP app which includes an InkCanvas, as such, I want to store the contents as a variable so that I can show a preview of the canvas in the menu.
My question is, what is the best bitmap to use, as there appear to be a number of options.
The SoftwareBitmap is included in Windows.Graphics.Imaging, whereas the BitmapImage is part of Windows.UI.XAML.Media.Imaging, both of which are available in a UWP app.
Can the UWP Image class for displaying images use either of these formats?
Which is most appropriate in my case?

So having done much experimenting, it seems for use with the Image control from Windows.UI.XAML.Controls, a SoftwareBitmap works fairly well.
A SoftwareBitmapSource can be assigned to the Image.Source, provided the SoftwareBitmap has BitmapPixelFormat.Bgra8 and BitmapAlphaMode.Premultiplied (or BitmapAlphaMode.None). From the Remarks section on the SoftwareBitmapSource page:
A SoftwareBitmap displayed in a XAML app must be in BGRA pixel format with pre-multiplied alpha values
All works nicely, now to work on scaling the bitmap down as the difference in size between the InkCanvas and Image make the thumbnail/preview look poor.

Related

Image manipulation in C#

I want to copy an image with all its parameters, including the manipulation data (scale, rotatio etc).
I'm creating a new image control and copy the source and size but can't find a way to set the same manipulation data.
I'm using System.Windows.Controls.Image and i have the ManipulationData object of the source image.
Have any idea?
Thanks
There's very good nuget package available for this..
https://www.nuget.org/packages?q=Tags%3A%22Magick.NET%22
For example to crop or resize an image:
MagickImage image = new MagickImage("filepath.jpg");
image.Crop(new MagickGeometry(424, 448, 224, 224));
image.Resize(123,234);
image.Write("output.jpg");
You can use RenderTargetBitmap to render any UIElement to bitmap:
The class exists in both, WPF and Windows Store Apps, however the usage is slightly different.
WPF Links:
- https://msdn.microsoft.com/en-us/library/system.windows.media.imaging.rendertargetbitmap(v=vs.110).aspx
Windows Store Links:
https://msdn.microsoft.com/library/windows/apps/dn298548
http://social.technet.microsoft.com/wiki/contents/articles/20648.using-the-rendertargetbitmap-in-windows-store-apps-with-xaml-and-c.aspx#Use_its_Pixels

How to display scaled image without anti-aliasing?

Question
How can I scale an image in XAML quickly without anti-aliasing applied?
Background
I am trying to make a pixel editor as a Windows 8 XAML/C# app. I'm using c#/XAML because most of my experience is with c#/WPF.
Method 1: WriteableBitmap + Image control. Originally, I used a WriteableBitmap to store and edit an image. That image is displayed in a resized XAML Image control. The problem is that the image does not get scaled properly because of anti-aliasing. (XAML does not seem to provide the BitmapScalingOptions that are available in WPF)
Method 2: Redrawn WriteableBitmap + Image control. Next I tried writing my own scaling, where I take my original image and write to a larger WriteableBitmap so that the scaled image is pixelated. The scaled image is then presented inside a XAML Image control. This process is slow and inefficient.
Method 3: SharpDX + Direct2d ?? I am pretty sure a solution exists somewhere between SharpDx, SurfaceImageSource, and Direct2d. Event still, I can't quite figure out how to display a SharpDx.WIC.Bitmap inside a Windows.UI.Xaml Image control, and am generally getting lost in the documentation.
What exactly is a recommended setup for achieving my desired end? Are there c# samples available which might point me in the right direction?
I don't know if you mean by scaling it by resizing it with the mouse or just with a button click to auto scale to a predetermined size.
But the thing you can do is to use an Image panel and then, just set it to image.Stretch = Stretch.Fill; so if you override and create a method for the Resize event of the Image Panel, your image will take the size to fill the Image panel.

Quickly scale/crop a bitmap image stream for display in WPF

Question:
What is a fast way to scale and/or crop a bitmap provided from a WritableBitmap for display in the UI?
Requirements:
Have Low CPU usage
Handle large images (5 Megapixel, abt 2500x2000 pixels)
Resize and/or crop to the same resolution/area as the UI element the bitmap is displayed in.
Use WPF
Specifically, it must allow a 14FPS 5 Megapixel camera image stream to be displayed in a WPF UI element at full speed.
Update:
I have been able to speed up the drawing quite a bit by painting to a Canvas control using an ImageBrush as follows, where m_bitmap is my WriteableBitmap:
ImageBrush brush = new ImageBrush();
brush.ImageSource = m_bitmap;
brush.Stretch = Stretch.Uniform;
canvas.Background = brush;
I'm now able to get the full 14FPS, though it still using about 20% CPU, so I'm not sure how well it preform if I add another camera or two (the plan is to have 4 or so running).
Another thing I think might be slowing down the drawing is the images are in a mono, Gray8, format, not the standard RGB32 (or is it bgra32 for WPF?) format. If I understand correctly, the image has to be converted to the standard format to be displayed, which would add significant overhead to each frame's drawing time.
Some background:
I'm currently working with a 5 Megapixel, 14 FPS, video camera and am trying to get the frames to render to the screen at full speed. I would like to do this using WPF.
I currently have an example in WinForms that runs full speed for an unscaled image, but (as I would expect) it has major trouble if I set the pictureBox.SizeMode = Zoom;. The example reads raw data directly from the camera stream to a buffer and then copies the data from the buffer into the bitmap set to the PictureBox control. The copy algorithm uses LockBits to speed things up.
I converted that example into WPF, rewriting the parts using Bitmap objects to instead use WritableBitmap objects and an Image control instead of PictureBox. Unforunately this is not able to render the stream to the screen at any decent rate, scaled or unscaled. Both have significant CPU load and very slow updates.
The performance when rendering to the screen is turned off is great. It is able to process the image stream at full speed and resolution while using around 3% CPU and less than 100MB memory.
Note: when I say rendering to the screen is turned off, the WritableBitmap is still being continuously updated, only is not set to the Image control.
I've seen a lot of discussion about getting fast bitmap updating in WPF, but have been unsuccessful in getting it to work at an reasonable speed/cpu load. Also I would like to have the image scaled in such a way that I can see the whole image.
I imagine the key will lie in some sort of scaling/crop combination that needs to be done so that WPF will not try to render(cache?) all 5 million pixels, but only those on the screen, and only at the current screen resolution. I imagine/hope this can be done fairly easily and without too much hit to memory or CPU, but currently have no idea how to do so. I have found the DecodePixelWidth and DecodePixelHeight properties, but those are only applicable when loading an image from a file to a BitmapImage.
Did you have a look at the following post?
Resizing WritableBitmap
If it does not solve your problem, I have more questions for you:
What is the resolution of your image?
Is the size of you UI element constant? What's its size?
Edit:
After your edit, I noticed that you want to display a BitmapImage in Gray8 PixelFormat, why don't you try to set this property when creating your BitmapImage (m_bitmap)?
m_bitmap.Format = PixelFormat.Gray8; // could not test
I am certain that taking your 8 bits/pixel and multiplying the amount of bits needed per pixel by 4 while not gaining any quality is slowing down your application. Especially because you run operations on 32 bits per pixel images when you could be running those operations on 8 bits per pixel images.
While its interface is a bit old-fashioned, I believe that convert (see http://en.wikipedia.org/wiki/ImageMagick) is very often used (and may in fact be the industry standard).
Edit: StackOverflow has about 2,300 question tagged with imagemagick here. See for example What is the difference for sample/resample/scale/resize/adaptive-resize/thumbnail operators in ImageMagick convert?
The OP for https://apple.stackexchange.com/a/41531 decided to go with ImageMagick. And the accepted answer to Efficient JPEG Image Resizing in PHP also suggests ImageMagick, with 19 votes.
However, I don't know whether ImageMagick is capable of meeting your requirements of 14FPS, 5 Megapixels.
The only answer to Recommendation for real time image processing tools on Linux suggests a fork graphicsmagick, which seems to also be available for Windows.

change the size of writeablebitmap

I was wondering if it was possible to change the size of a WriteableBitmap in WP7. I have noticed that the default size is 640x480, and my windows phone application is in Portrait mode, so I would like the height of my writeablebitmap (which I am using to overylay a live grayscale camera image) could be increased accordingly (while ofcourse keeping the same aspect ratio). I have not been able to find anything regarding this anywhere?
Why not instead create a bitmap of the desired size using the relevant constructor?

.Net & C#: Trying to have a transparent image on a button (assigned from IDE)

Using VS2005 and C#.
Having a button in a form and an image from a resource, the image does not have transparency.
How can I have transparency when assigning the image from the IDE ?
Thank you.
Open the image in an image editor (Paint.NET and GIMP are free) and add the transparencies wherever you need to.
It will all work once the image actually has transparent pixels.
You can also use a couple methods of the Bitmap class to do this:
Bitmap b = Properties.Resources.MyImage;
b.MakeTransparent(b.GetPixel(0, 0));
I don't really understand what you are asking. You can use an image with transparency on a button as long as the image type you are using supports transparency - such as .png.
Edit: I read your question again and it is still confusing, but maybe you meant to say that you want to add transparency to the image? If so, you would have to use an image editor to add the transparency and save it in a format that supports this. Paint.Net is a good free tool for this.

Categories