How to remove image.Source from memory - c#

I have a problem when I add Images in a wrapPanel, it refuses to load if there are too many images in memory.
In fact, when I create an Image control and its source comes from a URL (from which it has to download the image), delete the Image control and recreate one with the same source, the image appears directly but there is no time to download the image like the first creation of the control.
How can I remove the image from memory?
Here is my code:
Image image = new Image();
image.Width = 60;
image.Height = 60;
image.ToolTip = StringExtension.GetTextBetweenTwoWord(Utilities.resource.EmojiesLink[i], "/72/apple/271/", "_").Replace('-', ' '); // name of mood
image.Stretch = Stretch.Fill;
image.Source = new BitmapImage(new Uri(Utilities.resource.EmojiesLink[i]));
image.MouseDown += new MouseButtonEventHandler(ExtraMoodFromWebsiteMouseDown);
wrapPanel_moodFromInternet.Children.Add(image);
P.S.: it's in WPF

You can release an object from memory by calling the dispose method.
https://learn.microsoft.com/en-us/dotnet/api/system.drawing.image.dispose?view=dotnet-plat-ext-5.0
Image image = new Image();
image.Width = 60;
image.Height = 60;
image.ToolTip = StringExtension.GetTextBetweenTwoWord(Utilities.resource.EmojiesLink[i], "/72/apple/271/", "_").Replace('-', ' '); // name of mood
image.Stretch = Stretch.Fill;
image.Source = new BitmapImage(new Uri(Utilities.resource.EmojiesLink[i]));
image.MouseDown += new MouseButtonEventHandler(ExtraMoodFromWebsiteMouseDown);
wrapPanel_moodFromInternet.Children.Add(image);
image.Dispose(true);

Related

set resolution of image loaded on canvas wpf c#

I am working on canvas and loading an image on it. How do I set resolution of my image to 640X480 pixels? decodepixelheight and decodepixelwidth not working.
ImageBrush brush = new ImageBrush();
BitmapImage src = new BitmapImage(new Uri(("C:\\Users\\i2v\\Desktop\\GoogleMapTA.jpg"), UriKind.Relative));
src.DecodePixelHeight = 480;
src.DecodePixelWidth = 640;
brush.ImageSource = src;
// brush.Stretch = Stretch.None;
canvas.Background = brush;
canvas.Height = src.Height;
canvas.Width = src.Width;
BitmapImage implements the System.ComponentModel.ISupportInitialize interface. This means that its properties can only be set between calls of its BeginInit and EndInit methods:
var src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(#"C:\Users\i2v\Desktop\GoogleMapTA.jpg");
src.DecodePixelHeight = 480;
src.DecodePixelWidth = 640;
src.EndInit();
canvas.Background = new ImageBrush(src);
Note that you would usually not set DecodePixelWidth and DecodePixelHeight at the same time, since this might disrupt the native aspect ratio of the image. Set either one or the other.

How can I get the object of effect-applied source

I applied customized pixel-shader effect to an image.
var eff = new Shaders.PixelateEffect();
eff.HorizontalPixelCounts = 15;
eff.VerticalPixelCounts = 15;
IMG1.Effect = eff;
Then I tried to merge and overlay between the effect applied image(IMG1) and another image.(IMG2)
But, IMG1.Source bring me an original image.
ImageUtils.OverlayingImages(IMG1.Source, IMG2.Source, x, y);
How can I get an updated image source?
it happened same when I rotate the image.
Do I need to capture the image with RenderTargetBitmap?
Thank you in advance.
I've solved it like this with RenderTargetBitmap. anyway, thank you for the comments.
var eff = new Shaders.PixelateEffect();
eff.HorizontalPixelCounts = 15;
eff.VerticalPixelCounts = 15;
BitmapSource bitmap = (BitmapSource)IMG1.Source;
var r = new Rectangle();
r.Fill = new ImageBrush(bitmap);
r.Effect = eff;
Size sz = new Size(bitmap.PixelWidth, bitmap.PixelHeight);
r.Measure(sz);
r.Arrange(new Rect(sz));
var rtb = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight, 96, 96
, PixelFormats.Default);
rtb.Render(r);
// here's the updated source with the custom effect.
IMG1.Source= ImageUtils.RenderTargetBitmapToBitmap(rtb);

Set position of pushpin - BingMaps

On my windows store app, im using a bings maps, and im trying to add a pushpin with an image
to do so , im doing this piece of code
Bing.Maps.Location center = new Bing.Maps.Location();
center.Latitude = 40.130066068147585;
center.Longitude = -8.338623046875;
Map.Center = center;
Map.ZoomLevel = 12D;
var pushpinLayer = new MapLayer();
pushpinLayer.Name = "PushPinLayer";
Map.Children.Add(pushpinLayer);
var location = new Location(40.130066068147585D, -8.338623046875D);
Image pinImage = new Image();
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri("ms-appx:///Assets/POI_Red_Ipad#2x.png", UriKind.RelativeOrAbsolute);
pinImage.Width = 20;
pinImage.Height = 30;
pinImage.Source = bitmapImage;
pushpinLayer.Children.Add(pinImage);
it adds the pushpin image but it appears on the top left corner of the map, i dont know how to set its position to use the localtion variable :\
Ok so you just have things a little out of order. The first part is correct:
Bing.Maps.Location center = new Bing.Maps.Location();
center.Latitude = 40.130066068147585;
center.Longitude = -8.338623046875;
Map.Center = center;
Map.ZoomLevel = 12D;
Next, instead of creating a maplayer you would instead create your pushpin image:
Image pinImage = new Image();
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri("ms-appx:///Assets/POI_Red_Ipad#2x.png", UriKind.RelativeOrAbsolute);
pinImage.Width = 20;
pinImage.Height = 30;
pinImage.Source = bitmapImage;
Then you can create your location:
var location = new Location(40.130066068147585D, -8.338623046875D);
Here is where it is different. You do not need to create an instance of the MapLayer class, instead assign the element (image in your case) and location - then add it to to the map.
MapLayer.SetPosition(pinImage, location);
Map.Children.Add(pinImage);

Printing XPS document with image. Different image size when set different dpi

I printing XPS document with images, that contains QR-codes.
Image creating sample here:
Image image = CreatePresentation(qrCode);
image.Height = 200;
image.Width = 200;
image.HorizontalAlignment = HorizontalAlignment.Center;
image.VerticalAlignment = VerticalAlignment.Center;
image.Stretch = Stretch.None;
where
public static Image CreatePresentation(System.Drawing.Image source)
{
Stream stream = new MemoryStream();
source.Save(stream, ImageFormat.Png);
Image image = new Image();
BitmapImage src = new BitmapImage();
src.BeginInit();
src.StreamSource = stream;
src.EndInit();
image.Source = src;
return image;
}
When i have monitor dpi=96 then image size on printed page (on paper after printing) more larger than when i have montor dpi=120.
How i can print images with the same size on different dpi?
When i replaced
image.Stretch = Stretch.None;
on
image.Stretch = Stretch.Fill;
image began print correct

Assign dynamically generated image to ToggleButton.Content

I have to put dynamically generated image
var img = new Bitmap(..);
// draw something on img canvas ...
To the ToggleButton background. When I assign generated image to ToggleButton.Content property I see "System.Drawing.Bitmap" string, not the image itself. It looks like ToString() method is used for Content property. How can I show generated image instead?
If WPF does not have an appropriate converter it just calls the ToString() method, the Bitmap format is unsuitable, what you normally want to use is an Image with a source that is a BitmapImage, there are several ways to do conversions between the different formats.
Here is one method that does a conversion from Bitmap to BitmapImage:
public static BitmapImage BitmapToBitmapImage(System.Drawing.Bitmap bitmap)
{
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
BitmapImage bImg = new System.Windows.Media.Imaging.BitmapImage();
bImg.BeginInit();
bImg.StreamSource = new MemoryStream(ms.ToArray());
bImg.CreateOptions = BitmapCreateOptions.None;
bImg.CacheOption = BitmapCacheOption.Default;
bImg.EndInit();
ms.Close();
return bImg;
}
Note that ImageFormat.Png is slower than uncompressed formats but it retains the transparency if there is any.
Now you should be able to use this as the Source of an Image control and this Image control as the content of the button.
"Content" property is concerned with what you write on the surface of the ToggleButton. You need to initialize the "Background" property of the UI element. Here is one example:
PixelFormat pf = PixelFormats.Bgr32;
int width = 200;
int height = 200;
int rawStride = (width * pf.BitsPerPixel + 7) / 8;
byte[] rawImage = new byte[rawStride * height];
// Initialize the image with data.
Random value = new Random();
value.NextBytes(rawImage);
// Create a BitmapSource.
BitmapSource bitmap = BitmapSource.Create(width, height, 96, 96, pf, null, rawImage, rawStride);
ImageBrush imgBrush = new ImageBrush(bitmap);
myToggleButton.Background = imgBrush;
I created the image using the following article http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapsource(VS.85).aspx

Categories

Resources