Android.Graphics.Bitamap equivalent in Xamarin IOS - c#

I'm developing custom control on .Net MAUI. For my case, I have to update 100's of points at each invalidate. So I'm going for native rendering. Here for Android, I have rendered points on bitmap and rendered the bitmap once and this performance is fine for me and the same had to dine with MU+
I'm new to IOS native's, and I tried to achieve the same as above using ImageContext as below,
UIGraphics.BeginImageContextWithOptions(image.Size, false, 0);
image.Draw(new CGPoint(0, 0));
//Drawn needed shapes here using Image Context
image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
Finally drawn the stored images to screen. But this doesn't look performance effective on my case.
My case is store the existing rendering to one object and render current points with the existing one. Please suggest if it can be achieved using some cases too..

Related

Winforms: Capture part of PDF image to OCR

This is a C# winforms question.
The process I am trying to achieve is the following:
Using AxAcroPDFLib I'm loading a pdf file to the form
I want the user to be able to specify a square on that PDF and create a bmp from it
That bmp will then be loaded to a OCR to become text
What is my issue:
Step 1 and 3 are easy to do, the problem is how to allow the user to draw a square on top of the AxAcroPDFLib for a screenshot.
I already got different ways to draw squares on native winform components, but AxAcroPDFLib does not support mouse down, up, move, etc and paint events.
There is the option to convert the PDF to bitmap and display it on a picturebox and deal with events for drawing the square. Problem with that approach is that my PDF's are usually more than two pages, and I would like to avoid the conversion pdf to bmp due to changes to image quality that will impact on OCR.
I came to think that maybe something that works as the windows snippingtool would do the the job. My application would get the screenshot, temporarily save the image on disk (must be a file for OCR), I would then pass it to the OCR and done. Hard part, I could not think on how to take the screenshot of part of the PDF.
Do anyone here have any suggestion to different components or workarounds to deal with the requirement above? I am using Adobe just because it is simple, but maybe there are other components better suited to handle my requirements? I googled but haven't found any free ones, trying to avoid paid options.
Thanks
At some point in this process, the PDF is going to have to be rasterized in order to be passed to the OCR, so I don't totally understand your objection to converting it to a bitmap. If you're okay with Snipping Tool's behavior, then you must be OK with the quality of the PDF control's PDF->screen rasterization. If that resolution is acceptable, why not just capture the control's content to a Bitmap and let the user draw the selection marquee over that Bitmap?
Here is code I'm using to capture a control's contents to a Bitmap in Windows Forms. One caveat is that this is really a screen capture, so any windows or controls that overlap the control's visible area will be captured in the image.
using (Bitmap b = new Bitmap(width, height))
{
using (Graphics g = Graphics.FromImage(b))
{
Point p1 = myControl.PointToScreen(new Point(0, 0));
g.CopyFromScreen(p1.X, p1.Y, 0, 0, size);
}
// do stuff here with your Bitmap
}

How to get a ScrollViewer to zoom in to see individual pixels?

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.

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.

overlay images on top of an existing image (web)

My goal is to display a large rectangular image in a section of a webpage that will act as a background for other, smaller images to be laid on top of. The smaller rectangular images will be dynamically selected based upon database entries. I was able to create a java applet that drew the larger base rectangular image and then drew the smaller images over the base image. This worked very well.
I am attempting to recreate the functionality using C# in Microsoft Visual Web Developer 2010. I have found system.drawing functionally that may work, but haven’t found a web based solution yet. Any help would be appreciated.
If I understand correctly, you want to overlay smaller images on top of another image. At the end you'll end up with one image to display. This is easy to do in C#:
string image1 = #"c:\image.jpg";
string image2 = #"c:\image2.jpg";
System.Drawing.Image canvas = Bitmap.FromFile( image1 );
Graphics gra = Graphics.FromImage( canvas );
Bitmap smallImg = new Bitmap(image2);
gra.DrawImage( smallImg, new Point( 70, 70 ) );
canvas.Save( #"c:\newimage.jpg", System.Drawing.Imaging.ImageFormat.Jpeg );
My two cents here... Another thing which helped me on .NET 2.0 and 3.0 was explicitly deleting the Image, Graphics and Bitmap objects after you are done, specially when you would be accessing any of the image sources (image1, image2 and smallImg above) within the same routine.
Deleting these objects will instantly release the file locks. I experienced that the garbage collector wouldn't necessarily clean these up for me at the desired time, even if I made a separate sub-routine for my image manipulation.

Rendering DirectX 3D graphics onto an Image directly, using C#

The project I'm working on requires the ability to transform any of the 4 corners of an image. As GDI+ unfortunately doesn't have this capability, we're resorting into using DirectX's 3D graphics.
While I have a square mesh with a texture showing successfully on-screen, I need to be able to generate an image from this rendering, with the background set to transparent. Is there a way to efficiently achieve this?
Preferably, I'd like to do this without using a Control for initializing a device. Alternatively, I don't mind the option of creating a custom, invisible Control that will generates an image for me.
Edit:
Actually, I just realized a transparent background is strictly not necessary, but it would help the performance of our project a bit.
Anyway, I've had some luck doing something like this, but it is excessively slow. Perhaps there's a better method?
// Create a surface to render an image to
Surface mSurface = mDevice.GetRenderTarget(0);
// Render the visualization
mDevice.Clear(ClearFlags.Target, Color.Transparent, 1.0f, 0);
mDevice.BeginScene();
/* Do some amazing stuff */
// Exit rendering
mDevice.EndScene();
mDevice.Present();
// Render the bitmap images
GraphicsStream mGraphics = SurfaceLoader.SaveToStream(
ImageFileFormat.Bmp, mSurface);
Image mImage = new Bitmap(mGraphics, false);
Well if you use D3D for doing the final rendering to screen then you can easily do the things you are talking about using render-to-texture.

Categories

Resources