Nine-Patch Image in Windows Phone - silverlight

In Windows Phone UI Design Principle, MS recommended use solid color rectangle or coding-gradient for Control Background to avoid incompatible in multi-screen. But in many requirements, using image as Control Background is necessary. Then, 9-patch image technique is used. In Android and IOs, it was support in core, but in WP it is lacking. I try to use it in WP by 3 approaches:
Using 9-cells Grid: clip image into 9 patch and lay them into cells. It works ok, but i afraid app performance reduce when has many control.
Using Custom Brush: only custom Brush to draw 9-patch image as ImageBrush, but seem MS not allow for custom Brush.
Using FramworkElement: like Rectangle, Ellipse... i want to create a FrameworkElement can draw a 9-patch image. But, can't use low-level render.
How can i implement 2nd and 3th approach?

I created a lib for Windows Phone which do exactly as Android NinePatchDrawable. You just need to set a bitmap image.9.png, the width and heigh... And done!!! you have you new image scale to the size you want. Enjoy it :). In the future I will add more option :).
GitHub link

You can compensate for the lack of low-level rendering and custom brush by using a WriteableBitmap: http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(v=vs.95).aspx
This way, you have complete control on how to render your background, then you can assign it to a single Image control. But it's way more complicated than the "use a grid with 9 image controls" method, and the performance improvement is probably insignificant.

Related

Can I create a motion colorizing pixel shader in WPF?

I have a video playing of lines being drawn on the screen. Is it possible to create a pixel shader (for WPF) that turns newly colored pixels a certain color for N milliseconds?
That way, there can be some indication to the user to movement on the screen when the lines don't move often and the user isn't always looking at the screen.
You can use DirectShow. Its written in unmanaged code, so you need to use this wrapper DirectShow.NET in order to use it in your C# application which is running in managed environment (samples are included, even with EVR which stands for Enhanced video Renderer which means MUCH better video quality). And when you will be passing a control handle to wrapper method for setting the video output, you need a WinForms control, because only from them you can get your desired control handle. That WinForms control you can then host in your WPF application using the WindowsFormsHost control provided for such situations when you need to use some WinForms control(s) in a WPF application. Its just theory, so i dont know if its an ultimate solution for you.
BTW: The whole idea is based on fact, that DirectShow is just some query constructed from separated filters. Renderer is a filter (EVR, VMR-7, VMR-9). Sound player is a filter. And they are connected through their pins. Its like a diagram. Electronic schema or something like that. And you can put for example Grey scale filter in there. And voila, video output will be greyscale. There is a bunch of tutorials for that. And completed simple filters as well. Unfortunately, filters must be written in C++:(
PS: I never said its gonna be easy:D

Is there something like Expression Design's skeleton strokes in Silverlight?

Expression design has a feature called Skeleton strokes which allows you to use arbitrary vector/bitmap as a stroke.
http://msdn.microsoft.com/en-us/library/cc294949(v=expression.30).aspx
http://msdn.microsoft.com/en-us/library/cc294775(v=expression.30).aspx
The stroke is treated as a skeleton and the brush is painted following the stroke. Using an ImageBrush in silverlight doesn't seem to have the same effect. Rather it just renders the ImageBrush as if it would render the fill but with the fill portion cut out.
BTW, I'm using Silverlight 5
Silverlight doesn't support this feature. At least not out of the box.

Improving WPF Canvas performance

I am developing a Maps like application using WPF. I have ~10,000 PathGeometry, Shapes added to the canvas. I have added ScaleTransform and TranslateTransform for zooming and panning controls.
The problem I'm facing is, when I zoom or pan, there is slight lag. Is there a way to organize the data so that I handle only the Shapes that are visible?
Any hints on making it more efficient will be helpful and appreciated.
What kind f stuff are you putting on the canvas? If using pathGeometry, are you enclosing them in Path class? If so, Path has FrameworkElement in its superclass hierarchy, which is responsible for massive performance loss.
Take a look at my question here. Although it is about Shape class, but the reason of performance degradation is the same, FrameworkElement.
If you are doing so, the solution is to use PathGeometry instead, and enclose it in DrawingContext of a DrawingVisual using DrawingContext.DrawGeometry() method.
Here are some links that should help.
Path Geometry
DrawingContext.DrawGeometry()
Optimizing Performance: 2D Graphics and Imaging
And draw the shapes yourself, using combination of lines, and other things provided by classes derived from Geometry class (ArcGeometry, PathGeometry etc).
This should help.
If you want the ultimate in performance for immediate drawing in WPF, then check out WriteableBitmapEx. This is an excellent open source library, which I recently contributed to. it provides GDI-like drawing capabilities on WriteableBitmap and is compatible with Windows Phone, WPF and Silverlight. The API is simple, you get blitting, polygons, lines and simple shapes etc... You won't get datatemplates and gradient brushes however.

Make part of an image transparent

I want to put an image on a button, but I want part of the image to be transparent. How do I do this?
Try the Image.OpacityMask property. You can give it a brush that specifies the region you want to be transparent.
EDIT: From MSDN:
There is no direct support for
color-keying a bitmap in WPF.
However, it is fairly easy to
implement on your own. Dwayne has
implemented a ColorKeyBitmap on his
blog:
http://blogs.msdn.com/dwayneneed/archive/2008/06/20/implementing-a-custom-bitmapsource.aspx
I believe it links to the code on
Codeplex as well. You could also
accomplish this simply by reading your
bitmap into system memory, iterating
through all the pixels and setting
their values yourself, and
constructing a new bitmap out of that
array.
Use a paint program (I use Paint.Net) to change the area you want transparent to an alha=0 color. Then save the image (mine was JPG) as a PNG. Seemed to work fine for me in the WPF Image control.

How can I stretch bitmap in WPF without smoothing pixels

I'm working on SEM image processing application, written in WPF. I have an image display control, derived from Canvas, which displays image & overlays using DrawingVisuals (one for each "layer"). It also implements Zoom & Pan using scale & translate transform, applied on DrawingVisuals.
When I zoom in the image to see individual pixels, they are displayed smooth, evidently using bilinear filtering to stretch the bitmap (no surprise, as WPF is rendered through Direct3D). However, for my use case, I would rather see individual pixels as sharp boxes, as usual in any image editor like Photoshop. That's why user of my app zooms the image -> to be able to operate on pixel level.
Is there such option in WPF (other than manually stretching the bitmap before displaying it)? I was not able to find anything.
thanks in advance,
Zbynek Vrastil
Czech Republic
Finally found an answer, with some help from Experts Exchange. Class RenderOptions defines attached property BitmapScalingMode, which can be set to NearestNeighbor. So,
RenderOptions.SetBitmapScalingMode(imageDisplay, BitmapScalingMode.NearestNeighbor);
does the trick.
Zbynek Vrastil
Hate to put a dampener on things, but if NearestNeighbor works like GDI+, then this will give you a limited success. As you increase magnification in areas of high contrast you might not get the desired results. In GDI+ you find blacks becoming blue, and whites becoming red - again I stress in areas of high contrast! If this isn't the case in WPF, think yourself lucky!
Perhaps a WCF developer could confirm that?
I've found that there are more options to consider, but I can only speak for the GDI+ Graphics class, which might be useful to someone.
Graphics graph = e.Graphics;
graph.InterpolationMode = InterpolationMode.NearestNeighbor;
graph.CompositingQuality = CompositingQuality.AssumeLinear;
graph.SmoothingMode = SmoothingMode.None;
This works for me. I think the SmoothingMode is the trick. Hope this helps someone else out there.

Resources