Does anyone know the solution to layering PNG images for windows UWP app?
While preserving the transparency?
(this solution does not work in UWP application)
Merge two png images with transparency and retain transparency
End goal is to merge the PNG files to an Image object so it can be added to a Grid control.
One possible solution is using Blit method in WriteableBitmapEx. This method copies (blits) the pixels from the WriteableBitmap source to the destination WriteableBitmap (this) and following is a simple sample.
var writeableBmp = new WriteableBitmap(1, 1);
var image1 = await writeableBmp.FromContent(new Uri("ms-appx:///Assets/image1.png"));
var image2 = await writeableBmp.FromContent(new Uri("ms-appx:///Assets/image2.png"));
image1.Blit(new Rect(0, 0, image1.PixelWidth, image1.PixelHeight), image2, new Rect(0, 0, image2.PixelWidth, image2.PixelHeight));
//BlendedImage is a Image control in XAML
BlendedImage.Source = image1;
I think you may use the two image control in Grid in Xaml and both have bind the transparency in viewModel.But I see the link and I also can't use it.May MS change the API.I also interesting in this.
Lumia Imaging SDK doing just what you want. It can blend 2 ore more images together.
You can find sample code here
Related
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..
I have an BitmapImage which is generated by application itself and have no sourceFile or URI. Now i have to convert this image to WritableBitmapImage in order to save it, according to this. But all the methods require sourceFile or URI.
There is no good way to extract the pixels from a BitmapImage after the fact.
As you note, if you have the source image then you can create a WriteableBitmap from that.
Since WritableBitmap and BitmapImage are both ImageSources they can be used the same way in most cases, so if you know you'll need access to the pixels when you create the BitmapImage then you can usually create a WriteableBitmap instead.
Once the BitmapImage is created and the original source is no longer available the closest you can get is to use RenderTargetBitmap to render the displayed Image control into a new bitmap from which you can extract the pixels with GetPixelData.
This will be a second generation image though and for large images will likely have lost data to resizing interpolation between the original and the rendering.
I'd recommend using a WriteableBitmap instead of a BitmapImage to begin with when generating the original image.
I'm creating an application for windows 8 metro, I need to render a framework control into an image and save it to hard disk but do not know how. Can I use SharpDX for this? How can I do? Thanks in advance for the help
justin.m.chase's approach certainly works if you do not mind adding dependencies to SharpDX assemblies. The RenderTargetBitmap class might be a good fit for what you are trying to accomplish.
// Render XAML to bitmap
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(elementToRender);
// get the pixels
IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
// write the pixels to a InMemoryRandomAccessStream
var stream = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
stream.Seek(0);
If you follow through this thread the limitations of Metro and the reasons why it won't work are explained. The essence of it is:
Sorry, but rendering Xaml to an element or capturing a screenshot of
your own app did not make it into the release version. It is by design
that an app cannot capturing a screenshot of another app.
A workaround mentioned is:
What I meant was - you can draw shapes, text and images using
Direct2D. The same shapes that you would otherwise draw with XAML UI.
I did not mean to imply that you can render XAML controls - just that
you can use Direct2D as an alternative to achieve same results albeit
with somewhat more effort.
I apologize that this is not possible. The WritableBitmap class' Render() method is current insufficient to accomplish what you are wanting. For the same reason a screenshot cannot be created at this time. But these are the things that are on the backlog! But, now you know.
Because I think this is a more correct answer I would like to reiterate the comment that Zeeshan made in the original question.
There is a extension method for that in winrt xaml toolkit.
http://winrtxamltoolkit.codeplex.com/.../WriteableBitmapRenderExtensions.cs
Install via nuget:
> Install-Package WinRTXamlToolkit.Composition
Add the using:
using WinRTXamlToolkit.Composition;
Render your xaml:
var bitmap = await element.Render();
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.
I am trying to let a user capture an image and add it onto the screen using an Image. However, I also need to resize this image down to about half size due to memory restrictions (12x 5MP images is never good on a phone...)
I am launching the camera task fine and it calls the Completed event. However, when I try and use DecodeJpeg I get a "The parameter is incorrect." exception.
Here is my code for resizing, where mx and my are int for dimensions. I have verified that there is something in the e.ChosenPhoto with a length of about ~5500:
WriteableBitmap bitmap = PictureDecoder.DecodeJpeg(e.ChosenPhoto, mx, my);
Image img = new Image();
img.Source = bitmap;
The first line is where the app crashes. Any ideas?
EDIT:
This also occurs with the result from the PhotoChooserTask....
Try using the System.Windows.Media.Imaging - Extensions.LoadJpeg method instead of PictureDecoder.DecodeJpeg. Also make sure that the stream is positioned at the beginning of the stream. If you have already used the stream you will need to reset it using:
MyImageStream.Seek(0, System.IO.SeekOrigin.Begin)
I had a lot of problems trying to get access to the original image, especially since BitmapImage automatically resizes images over 2000x2000. If you want an image larger than 2000x2000 you have to have access to the original stream and load it into a WriteableBitmap object
If you want to see some more complex image handling code including detecting resolution from image stream using ExifLib and rotating stream using the WriteableBitmap Extensions check out the BarcodeCaptureResult class for the Silverlight ZXing Library.
UPDATE: Since all you want is to resize an image given the e.ChosenPhoto result I pulled the code from The Silverlight ZXing library. This should work:
WriteableBitmap wbBarcodeImage = new WriteableBitmap(mx, my);
Extensions.LoadJpeg(wbBarcodeImage, e.ChosenPhoto);//Load JPEG from stream into our re-sized writeable bitmap
Note that you will need to use the correct height/width ratio, otherwise you will have a black bar at the bottom or side of the image. You can use ExifLib to detect the original image size and use that to scale (see GetWriteableBitmap method in BarcodeCaptureResult linked above)