Image rescale (downsize) with Silverlight - c#

I have an array of graphs, that are 2000x1000 pixels pngs. When I put them into a silverlight Image that auto-sized with the browser window, DisplayImage.Source = new BitmapImage(GetHeatmapURL()); they images look distorted and for some browser sizes much worse than for some others.
I want to fiddle with some setting that would improve the quality of this downsampling, is this possible? Am I doing something wrong? My first approach was to put the Image into a Viewbox. That looked even worse. Googling gives virtually nothing useful...
Any help much appreciated.
PS. I'm working with Silverlight 4.

You could check out the WriteableBitmapEx project on CodePlex which gives you a Resize() extension method for the Silverlight WritableBitmap class where you can use either Bilinear or Nearest Neighbor interpolation. Resizing with the Bilinear interpolation might give you something that looks better than the ViewBox resizing, but you would have to test it out.
var resized = writeableBmp.Resize(200, 300, WriteableBitmapExtensions.Interpolation.Bilinear);

When making use of the Viewbox you need to make sure to set Stretch to Uniform to respect the original height/width ratio.
In regards to the rendering of the image at the given aspect ratio and size; that is contingent on the framework.

Related

Properly Scale UI Images in Unity

I have a png that's size 150x100 , and I set the UI image to the same, but it makes a bunch of extra space around it (that can be interacted with). How do I fix this?
Image of Problem: https://imgur.com/a/2ILXY1t
Unity isn't adding extra space. The image itself HAS that space.
There are options to crop out the alpha space in Unity by using the sprite editor, but by my experience i prefer using a proper Image editor like Gimp. using one is the best way to handle your image assets.
To crop out the extra space you just have to reduce the canvas size.
Well, first you could check (in Unity) wether your Image has its property Preserve Aspect set to True.
You could click Set Native Size which is right below it, so the 'box' around your image will take it's size.
Edit: Nevermind the first two. I do not know why i thought they could solve it, i looked at your image again and i, too, think there are transparent pixels above and below it. So you should try this:
Then you could check whether your picture has any transparent pixels around it, using an image editor. If it has, you would need to cut them out.

increasing image quality of treeview icons?

I have a treeview that contains icons. The icons are ugly. and by ugly i mean low quality. and by low quality i mean something i would expect to see from a dos program
i would hope there would be a way to improve the image quality of the icons, but after looking around on microsoft's development site, I have yet to find a solution.
to be honest, at this point i don't even know what to look for. 'image quality' is very too broad of a phrase to search for (i've gotten very random results from google searches).
i am using an ImageList to store these icons in the TreeView. there really isnt much code to show that would be of use here - at least i dont think so.
sorry for the boring question.
Is this what you're looking for?
http://msdn.microsoft.com/en-us/library/system.windows.forms.imagelist.colordepth.aspx
The default value is set to 8-bit, so changing this property of your list will probably help. Essentially, just add the following line to your code:
imagelist.ColorDepth = ColorDepth.Depth32Bit;
It can be improved. What you need to do is to open it in photoshop or gimp and resample it at 3 times it size. Then resample it at 600 dpi and resize it down to 8 x 10.
Notice, that I specified to resize and not down size. You click on the pic and the corners have a handle for you to click on and size it down to the appropraite size. This way, the pixels are closer together.
Then, you use a very soft blur, I mean really soft. The secret is when it is printed. We print at 600 to 1200 dpi which is what will enhance the picture and that is what a printer has to keep in mind. When you print on glossy paper at 600 dpi, the pic comes out really nice and sharp.

Creating high resolution image

I have an image (png) with resolution 1600*1200 (96 dpi).
I have put some text on the image and then saved it to a file for it to be loaded using silverlight's deepzoom with the pivotviewer. The text is blurry when zooming in and I was wondering how I can make the text look sharper (only if zooming in a bit).
This is my first bit of programming with images/graphics, so any info would be great (i.e. links to read, concepts to understand etc)
JD.
I've never used these controls before, but you might end up having to override the zooming algorithm (if that's even possible, I don't know). If you have text in an image and you're not using vector-based images (SVG, EMF, WMF, etc.), any sort of stretching is going to be blurry.
A different zooming algorithm, if it's a possibility, can decide how to stretch the pixels. For text, you're looking for something called "Nearest Neighbor" or maybe even "Bi-cubic" interpolation while the image is resizing. These methods are more expensive in terms of processing, so you might not get as smooth of a zoom as with the default interpolation algorithm (whatever it is).
There are some forum posts that start the same discussion, but with no real direction. Maybe you can follow them and see how they progress. I'm afraid I can't be of much help otherwise.
http://social.expression.microsoft.com/Forums/en-US/deepzoomcomposer/thread/dee528a2-06ae-4426-b096-5baafec499ff
http://weblogs.asp.net/bleroy/archive/2009/12/10/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi.aspx
In the last post they refer to the different interpolation algorithms in a BitmapScalingMode enumeration. One of those options is NearestNeighbor. There are also some examples of resized images.
Update:
In this article, the author takes a look at a way to change the quality of the image tiles that the Deep Zoom control uses (and he's using Silverlight!). The author effectively changes the way images are created with a few lines of code in his project:
if (bSmoothScaling)
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
}
In that list of assignments you can find the interpolation mode I've been mentioning, as well as some other things I wasn't aware of. The author does mention a significant impact on performance with everything set to "High Quality."
Hopefully you can take the concept and incorporate it into Silverlight somehow. Good luck!

How to convert a 32bpp image to an indexed format?

So here are the details (I am using C# BTW):
I receive a 32bpp image (JPEG compressed) from a server. At some point, I would like to use the Palette property of a bitmap to color over-saturated pixels (brightness > 240) red. To do so, I need to get the image into an indexed format.
I have tried converting the image to a GIF, but I get quality loss. I have tried creating a new bitmap in an index format by these methods:
// causes a "Parameter not valid" error
Bitmap indexed = new Bitmap(orig.Width, orig.Height, PixelFormat.Indexed)
// no error, but the resulting image is black due to information loss I assume
Bitmap indexed = new Bitmap(orig.Width, orig.Height, PixelFormat.Format8bppIndexed)
I am at a loss now. The data in this image is changed constantly by the user, so I don't want to manually set pixels that have a brightness > 240 if I can avoid it. If I can set the palette once when the image is created, my work is done. If I am going about this the wrong way to begin with please let me know.
EDIT: Thanks guys, here is some more detail on what I am attempting to accomplish.
We are scanning a tissue slide at high resolution (pathology application). I write the interface to the actual scanner. We use a line-scan camera. To test the line rate of the camera, the user scans a very small portion and looks at the image.
The image is displayed next to a track bar. When the user moves the track bar (adjusting line rate), I change the overall intensity of the image in an attempt to model what it would look like at the new line rate. I do this using an ImageAttributes and ColorMatrix object currently.
When the user adjusts the track bar, I adjust the matrix. This does not give me per pixel information, but the performance is very nice. I could use LockBits and some unsafe code here, but I would rather not rewrite it if possible. When the new image is created, I would like for all pixels with a brightness value of > 240 to be colored red. I was thinking that defining a palette for the bitmap up front would be a clean way of doing this.
Going from 32bpp to 8bpp indexed will almost always result in quality loss, unless the original image has less than 256 colors total.
Can you create another image that is a overlay with the affected pixels red, then show both of those?
Since you are going for brightness > 240, you can convert the overlay to grayscale first, then to indexed to get the overbright pixels.
You don't specify what you are doing with it once you have tagged the offenders, so I don't know if that will work.
Sounds like something you could do easily with a pixel shader. Even very early shader models would support something as easy as this.
The question is however:
Can you include shader support in your application without too much hastle?
Do you know shader programming?
EDIT:
You probably don't have a 3D context where you can do stuff like this =/
I was mostly just airing my thoughts.
Manipulating the picture pixel by pixel should be doable in real-time with a single CPU shouldn't it?
If not, look into GPGPU programming and Open CL.
EDIT AGAIN:
If you gave some more details about what the app actually does we might help a bit more? For example, if you're making a web-app none of my tips would make sense.
Thanks for the help everyone. It seems that this can be solved using the ImageAttributes class and simply setting a color remap table.
ColorMap[] maps = new ColorMap[someNum]
// add mappings
imageAttrs.SetRemapTable(maps);
Thanks for the help again, at least I learned something.

GDI+ Offscreen Buffered Scrolling

I am creating a custom control using C# GDI+.
Quick explanation...the control will be say 500 pixels on screen but will contain perhaps 500000 pixels of information. So although i'm only showing 500px at a time i need to obviously scroll in the horizontal plane (left & right). The tricky part is that each 500px chunk of bitmap takes a while (between 100ms - 1000ms) to render.
So my plan is to maintain a 1500px bitmap in memory. i.e. the 500px visible part and 500px either side of the visible area and draw the off-screen parts asynchronously as the user scrolls.
I would like some feedback, advice, criticism or examples of code to help me achieve this. It seems fairly straight forward but after a few initial test attempts its proving more difficult than one would imagine.
Thanks.
The effectiveness of this approach depends on, amongst other things, the amount of moving around the user will do. If the user is making small movement, then stopping to consider the new information, this could work. However, if the user is whizzing back and forth, you'll still have an issue.
Does your application lend itself to gradually improving the quality of the image - i.e. providing a quick usable image and then improving it as the user stops to consider it?
I had a similar problem a few years back. As dommer mentions, if you're processing chunks of the image before displaying them you're best off showing something and improving it later. If you're having problems blitting the original image, you've got something wrong with your method. GDI+ is very particular about pixel depth (you want 32bpp with alpha).
In our case, we processed in 500px tiles and padded out a tile around the visible view Ff the user scrolled outside the area we'd processed we blitted bits of the original image with a dark semi-opaque rectangle super-imposed on them. These chunks were queued for processing. As we processed chunks of the image (centre-out) they semi-opaque rectangles would disappear.
It worked reasonably well, was very responsive and very fast. It's very fast to blit the original bitmap onto the screen, and in our case the processing was usually very close behind. The effect of the tiles getting lighter was actually quite pretty.
Draw only the visible area.
Build a method
Bitmap DrawGraph(leftMargin, rightMargin) {...}
and then in OnPaint() do
Bitmap bmp = new Bitmap(e.ClipRectangle.Width, e.ClipRectangle.Height);
bmp = DrawGraph(e.ClipRectangle.Left, e.ClipRectangle.Right);
e.Graphics.DrawImageUnscaled(bmp, e.ClipRectangle.Location);

Categories