I'm making an app for Windows 8.1 where it is important to be able to zoom in and examine images in detail. If I just open up the bitmap and zoom in it looks like.
However when I load the image into my app and use the ScrollViewer to zoom in I get.
As it appears to be trying to interpolate pixel values for some sort of anti-aliasing.
How can I get it so that when I zoom in it shows (as best it can) the exact pixels of the image? In particular I'm using the image as the background to a canvas which is contained in a scroll viewer.
I've looked around on here and MSDN and found a pair of related questions, but as yet they don't seem to have solved my exact problem.
A discussion on WPF
A similar issue with a canvas
Older related question on pixel art
A way to use bitmap encoding (which I couldn't get to work)
Similarly phrased question
There is no easy way to go about this, your best option is to use DirectX to render the image much larger so that you can mitigate the effect of WinRT automatically interpolating pixel values.
As someone explained on MSDN and based on this outstanding request I can't see any other way to accomplish this.
Use Win2D
Win2D is a DirectX inter-op library for WinRT. With this you can render the image at a much larger size, and then set the default zoom level for the scrollViewier to be very small. Because of this when you zoom in it will appear to be that you can see the individual pixels without any fuzzy/blurry interpolation because you will actually be seeing groups of 64 pixels or so all as one color. I couldn't find any way to actually override what kind of interpolation gets done so this seems to be the best method.
Download Win2D as a NuGet package using Visual Studio, Win2D's
quickstart guide does a good job explaining some of the setup
Set up your canvas and the draw event and use the DrawImage function to render the image larger
<ScrollViewer x:Name="Scroller" ZoomMode="Enabled"
MinZoomFactor="0.1" MaxZoomFactor="20">
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" CreateResources="create"/>
</ScrollViewer>
In the canvas_draw function.
canvas.Width = original.Width * 10;
canvas.Height = original.Height * 10;
args.DrawingSession.DrawImage(bitmap,new Rect(0,0,original.Width*10,original.Height*10), new Rect(0,0,original.Width,original.Height), 1.0f, CanvasImageInterpolation.NearestNeighbor);
Make sure to set your canvas to be larger as well
In your code behind set the default zoom of your ScrollVieiwer to be appropriate so your image appears to be the same size.
In the page constructor
Scroller.ZoomToFactor (0.1f);
Other Ways Which I Looked Into and Didn't Work
Making the canvas very large and using BitmapEncoder/BitmapDecoder with the interpolation mode set to NearestNeighbor, this introduced lots of visual artifacts even when scaled to a power of 2 size
Render options only appear to be usable in WPF and not WinRT
It may also be possible to use some image manipulation library to simply make the bitmap 10x or so as large and then use that, but I ended up using Win2D instead.
Related
Recently I thought: "Let's set the 'resolution' from 16:9 to 16:9(1920x1080)" but i noticed that now all my positioning* code was off, and the size of pictures and text was way too small.
My problem now is, if I should just use the 16:9 aspect ratio or an fixed resolution (I don't know the benefits). But if I shouldn't use the aspect ratio, how to change the fixed resolution when the Project is ready, for example in the settings, without needing to rewrite all my code* and rescale all my images on the Canvas according to the resolution.
*For those of you who don't know what I mean with 'positioning', I mean setting the position of an Image on the Canvas, which obviously needs to be changed because the resolution is different. You could make something that detects your resolution and positions you image based on that, but idk if there is a better solution.
The best way to do this is during positioning ui using procentage also canvas Type which is displayed to resolution.
https://youtu.be/Tys6QWi9RpM
Solution on yt.
I am trying to write a drawing application that allows users to select two points on canvas and draws a line between those points pixel-by-pixel. In WinForms that would be an easy solution - create a canvas, get its bitmap, draw on the bitmap using the SetPixel method, and replace the canvas bitmap. I am wondering if there is a way to do this in a similar way in AvaloniaUI? From what I understood, it uses SkiaSharp under the hood. However, solutions to render SKCanvas on Avalonia.Controls.Canvas seem... hard. Although SKBitmap also has the SetPixel method. The question is not about how to draw a line - it is about how to set single pixels on Bitmap in AvaloniaUI and set this bitmap to the Avalonia.Controls.Canvas.
Here are some links I found:
https://github.com/AvaloniaUI/Avalonia/pull/2371
https://github.com/AvaloniaUI/Avalonia/issues/2492
AvaloniaUI - How to draw directly on the canvas - Unfortunately, I am not allowed to draw on the canvas itself.
Artifacts on Avalonia WriteableBitmap BitmapContext - unsafe code, three extension methods... while an option seems a little bit too complex.
P.S. As tempting as this may sound, drawing a rectangle-by-rectangle of size 1x1 as in the official documentation example (https://docs.avaloniaui.net/docs/controls/canvas) is also not allowed by the university.
P.P.S. I am not asking anyone to do the homework for me - in case you are worried about that please, consider this a framework comparison question, not a "please do that for me" one. I have found and linked solutions that I can use - it just seems to me that there should be a more easy way to achieve the result I seek. That's why I have asked the question - in case I missed something.
Doing a Jedi thing: this is not some student trying to lay off his work on other people. You can go by your business
UPDATED: you can swap bitmap on the image control: https://docs.avaloniaui.net/docs/controls/image
The original question (although poorly stated, my bad) was intented to clarify if there is a way to perform the SetPixel operation on the Avalonia bitmap. Unfortunately, currently, it doesn't seem like an available option: so the only way is to either create a custom drawing context OR control OR conversion between different Bitmap types (like System.Drawing.Bitmap or SkBitmap from SkiaSharp) to Avalonia.WriteableBitmap. All those solutions are referenced in the original question.
I have an application that scan Images from scanner but some scanners put a black border around the saved image.
How can I remove that black border?
Thanks so much for your participation.
I’ve had good luck in the past process images using the Magick.NET library. It’s available on Codeplex or you can install it using NuGet in Visual Studio. Documentation for the library is a little sparse, but it’s served me well in the past.
Depending upon the exact nature of the images you’re dealing with, you might be able to do something as simple as crop off the edges where the border is and then add a white (or whatever color; I just assumed that you were scanning text documents or something) border to bring the image back up to a standardized size. If having a standardized size doesn’t matter, then of course you can just leave the image cropped. If that sounds like a viable solution, here’s some code that should accomplish what you need:
using (MagickImage image = new MagickImage(#"path_to_original"))
{
int width = image.Width, height = image.Height;
image.Crop(width - 800, height - 800);
//if the image needs to be brought back up to a standarized size
image.BorderColor = new ColorRGB(System.Drawing.Color.White);
image.Border(100, 100);
image.Write(#"path_to_cropped_image_with_no_more_black_border_around_it");
}
You will, of course need to add your own values for just how much width you need to crop off/add back in.
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.
Is there a way to measure object pixels using WP camera(precisely Lumia 800).
i.e. if i have shape recognized(a square, for example) is there a way to measure width and height in pixels?
Not sure, but you may be able to use the SLARToolkit to do measure an object like you require...
If you allready know where the shape resides and are looking for a better/faster image editing library use Image tools. I've used them in the past to filter out everyhting but a particular shade of red thus making image recognition a lot easier