No bitmapimage in uwp? - c#

I need to enter an image source from the code in C#. In my previous projects (not in uwp) I would do the following:
imagename.Source=new BitmapImage(new Uri(stringPath));
but in UWP the BitmapImage class seems not to exist.
Is there something similar to use or any solution for this problem?

MSDN reckons BitmapImage is still a thing.
See here: MSDN help document
Its usage is a little different though:
<Image Loaded="Image_Loaded"/>
And the C#:
void Image_Loaded(object sender, RoutedEventArgs e)
{
Image img = sender as Image;
BitmapImage bitmapImage = new BitmapImage();
img.Width = bitmapImage.DecodePixelWidth = 80;
// Natural px width of image source.
// You don't need to set Height; the system maintains aspect ratio, and calculates the other
// dimension, as long as one dimension measurement is provided.
bitmapImage.UriSource = new Uri(img.BaseUri,"Images/myimage.png");
}

There is a BitmapImage API within UWP. Microsoft has a guide for its use too.
This is the code sample taken directly from the guide for the C# segment:
// Create Image Element
Image myImage = new Image();
myImage.Width = 200;
// Create source
BitmapImage myBitmapImage = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(#"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg");
// To save significant application memory, set the DecodePixelWidth or
// DecodePixelHeight of the BitmapImage value of the image source to the desired
// height or width of the rendered image. If you don't do this, the application will
// cache the image as though it were rendered as its normal size rather then just
// the size that is displayed.
// Note: In order to preserve aspect ratio, set DecodePixelWidth
// or DecodePixelHeight but not both.
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.EndInit();
//set image source
myImage.Source = myBitmapImage;
And this is the XAML segment:
<!-- Simple image rendering. However, rendering an image this way may not
result in the best use of application memory. See markup below which
creates the same end result but using less memory. -->
<Image Width="200"
Source="C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg"/>
<Image Width="200">
<Image.Source>
<!-- To save significant application memory, set the DecodePixelWidth or
DecodePixelHeight of the BitmapImage value of the image source to the desired
height and width of the rendered image. If you don't do this, the application will
cache the image as though it were rendered as its normal size rather then just
the size that is displayed. -->
<!-- Note: In order to preserve aspect ratio, only set either DecodePixelWidth
or DecodePixelHeight but not both. -->
<BitmapImage DecodePixelWidth="200"
UriSource="C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg" />
</Image.Source>
</Image>

Especially if you come from WPF you have to add the using directive
using Windows.UI.Xaml.Media.Imaging;
What was next in going from WPF to UWP is the image source string. It needs the absolute path:
imagename.UriSource = new Uri("ms-appx:/your_path");

Related

How to blur for background of grid on uwp?

grid background="white"
Now, I want to blur it that such as blur on ios.
Use Blur by UWPCommunityToolkit.
<Grid>
<Grid>
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="BlurBehavior" Value="25" Duration="0"
Delay="0" AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
</Grid>
<Grid>
<!-- Your Content -->
</Grid>
</Grid>
If you want to increase or decrease the amount of blur then change the value in behaviours.
If you want any code sample, check out this GitHub project.
UWP Hamburger Menu with Frosted glass effect and Swipe to Open/Close.
Opacity is not a blur effect.
To make a pure blur effect, you will can use the RendertargetBitmap or Win2D.
I prefere to use Win2D because the gaussian blur effect is explicit and can be more precisely configured :
using (var stream = await Content.RenderToRandomAccessStream())
{
var device = new CanvasDevice();
var bitmap = await CanvasBitmap.LoadAsync(device, stream);
var renderer = new CanvasRenderTarget(device,
bitmap.SizeInPixels.Width,
bitmap.SizeInPixels.Height, bitmap.Dpi);
using (var ds = renderer.CreateDrawingSession())
{
var blur = new GaussianBlurEffect();
blur.BlurAmount = 5.0f;
blur.Source = bitmap;
ds.DrawImage(blur);
}
stream.Seek(0);
await renderer.SaveAsync(stream, CanvasBitmapFileFormat.Png);
BitmapImage image = new BitmapImage();
image.SetSource(stream);
paneBackground.ImageSource = image;
}
If you want to read more about it, here is the MSDN page.
You can apply a blur using the Composition APIs with the Windows 10 Anniversary update. However, if you're trying to blur things that are behind the window or app, that won't be possible. On the other hand, if you have something like a picture behind your grid and want the picture be blurred then this will work.
I wrote an answer to a similar question here.

While Rendering Canvas control in Png I lost the background image

My application is a windows 8 store app . It takes a photo with the camera, then i draw over the image, and i want to save both the image and the drawing. What i have come result is only the drawing. i lost the background image.
Below you have my implementation :
XAML code:
(in place of having an Image control for the photo taken and a canvas for the drawing, i binded the photo = CurrentPicture as the background of the canvas)
<Canvas Grid.Row="1"
Grid.Column="0"
x:Name="InkCanvas"
Background="{Binding CurrentPicture, Converter={StaticResource WPhotoToCanvasBackgroundConverter}}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="0"
Width="1024"
Height="768" />
C# :
private async Task<IPhoto> RenderCanvasToPNG()
{
MemoryStream stream = await WriteableBitmapRenderExtensions.RenderToPngStream(InkCanvas);
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(System.IO.WindowsRuntimeStreamExtensions.AsRandomAccessStream(stream));
byte[] byteme = stream.ToArray();
var photo = new WPhotos(null, byteme, bitmap.PixelWidth, bitmap.PixelHeight, bitmap);
return photo;
}
Thank you a lot for your time :)
There isn't a direct way to extract the pixels from a BitmapImage or ImageBrush. I believe WriteableBitmapEx fakes this by finding the image's source URI and looking that up, but this method works only if the image was loaded from a URI. If it was streamed into the image then there is no way to extract it.
Instead, you can use RenderTargetBitmap to render your UIElements to a bitmap. Since this uses the Xaml rendering engine it has access to the ImageBrush used for the Canvas' background and should completely render the Canvas and its contents (barring non-renderable contents such as a MediaElement or SwapChainPanel).

Fit image to ShaderResourceView and preserve aspect ratio

I'm loading an image into a ShaderResourceView to be used as a background image. This is what I'm currently using:
ShaderResourceView.FromFile(_device, imagepath);
It loads the image into the background, but it stretches both dimensions without regard to the aspect ratio. Is there a way to load an image into the background and preserve aspect ratio?
Ideally ShaderResourceView would provide a setting to automatically respect the image aspect, but below is the next best option.
An existing post on SO fits the image to a specified size, then pads any extra space with whitespace and creates a new image. Link: https://stackoverflow.com/a/2001462/978622
Another post shows how to easily convert from an Image to a bytearray, which is one of the types ShaderResourceView can create a shader from. Link: https://stackoverflow.com/a/3801289/978622
My code which puts it all together:
var original = Image.FromFile(path);
Image resized = FixedSize(original, actualWidth, actualHeight);
var byteImage = ImageToByteArray(resized);
var srv = ShaderResourceView.FromMemory(_device, byteImage);

Performance of BitmapImage vs. ImageBrush

I tried searching around but I couldn't find an answer to this question: are there performance improvements in using an ImageBrush to fill a rectangle rather than creating a BitmapImage and setting its source property?
I have to render an high number of images (we are trying to push over 5000), and for now I'm creating them this way:
<Image x:Name="img" RenderOptions.BitmapScalingMode="LowQuality"
Source="{Binding Path, Converter={StaticResource StringToImageConverter}, ConverterParameter={StaticResource string}}" >
</ext:IdImage>
and in the converter:
System.Windows.Media.Imaging.BitmapImage image = new System.Windows.Media.Imaging.BitmapImage();
image.BeginInit();
image.UriSource = new Uri(value as String);
image.DecodePixelWidth = int.Parse((String)parameter);
image.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad;
image.EndInit();
return image;
NB: I have to use the converter to set the DecodePixelWidth property.
Using an ImageBrush I could freeze the brush thus, according to what I read, increasing the performance so I was wondering if I should change the way I build the images.
P.S. The Images are not static but are translated around.
I think that the problem is not in the code but in the architecture WPF.
If your problem is performance, for my personal experience developing XAML is necessary that the pc is preferably provided with a dedicated video card. However, many times even in very old pc with windows XP to thin the program I did install the updates direct X library
http://support.microsoft.com/kb/179113/en
XAML is based on directX
Try it and let me know

Save Image to file keeping aspect ratio in a WPF app

Hi I trying to scale a png image with a transparent background. I need it to be 250x250 pixel.
Horizontal and vertical centered and keeping the correct aspect ration. The possibility to set a margin.
This is what I got so far.
var img = new System.Windows.Controls.Image();
var bi = new BitmapImage(new Uri("C://tmp/original.png", UriKind.RelativeOrAbsolute));
img.Stretch = Stretch.Uniform;
img.Width = 250;
img.Height = 250;
img.Source = bi;
var pngBitmapEncoder = new PngBitmapEncoder();
var stream = new FileStream("C://tmp/test3.png", FileMode.Create);
pngBitmapEncoder.Frames.Add(BitmapFrame.Create(img));
pngBitmapEncoder.Save(stream);
stream.Close();
I know that its not using the Image object yet, and therefor just saves the image without scaling it. But I'm having trouble saving the Image object. It gives a compile error of cannot convert from 'System.Windows.Controls.Image' to 'System.Uri'
Hope someone can help me :-)
EDIT
Updated the code, to the version with the compile error. just changed
pngBitmapEncoder.Frames.Add(BitmapFrame.Create(bi));
to
pngBitmapEncoder.Frames.Add(BitmapFrame.Create(img));
And here is a list of my using
using System;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Image = System.Windows.Controls.Image;
What you're doing is similar to zooming in an editor on an image and expecting it to be reflected in the underlying image when you save. What you'll need to do is create a TransformedBitmap to modify the image and then add that to the Frames.
e.g.
var scale = new ScaleTransform(250 / bi.Width, 250 / bi.Height);
var tb = new TransformedBitmap(bi, scale);
pngBitmapEncoder.Frames.Add( BitmapFrame.Create(tb));
Update Regarding the aspect Ratio.
I need it to be 250x250 pixel
If the source image doesn't have a 1:1 ratio for height and width the scaling above meets the "I need it be 250X250" but will create distortion.
To get around this you'll need to either crop the image or scale the image so that just one dimension is 250 pixels.
To crop the image you can either use the Clip Property or a CroppedBitmap. To scale just one dimension you just use one dimension to determine the scale e.g. new ScaleTransform(250 / bi.Width, 250 / bi.width);

Categories

Resources