Out of memory exception after selecting images - c#

I want to show a list of selected images by user:
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
var fileName = e.OriginalFileName;
var photoStream = e.ChosenPhoto;
}
}
and
<Image Source="{Binding PhotoStream}" Width="200" Height="200"/>
the problem is after selecting 4 or 5 images, app hits memory limit and exits. I just want to show thumbnails of those selected images, like PhotoHub, how can I do that without consuming a lot of memory? thanks

As mentioned in the comments there are several ways to solve it, and as you mention you will probably need a thumbnail. Here are some methods I can think of right now which might solve your memory problem:
Method 1:
First using the MediaLibrary to find the same image, where you will get a stream to a thumbnail version, like this:
void task_Completed(object sender, Microsoft.Phone.Tasks.PhotoResult e)
{
if (e.TaskResult == Microsoft.Phone.Tasks.TaskResult.OK)
{
MediaLibrary library = new MediaLibrary();
Picture pic = library.Pictures.Where(p => e.OriginalFileName.EndsWith("\\" + p.Album.Name + "\\" + p.Name)).FirstOrDefault();
Stream thumbnailStream = pic.GetThumbnail(); // Stream to a thumbnail
}
}
For this to work you will also need to enabled the capability ID_CAP_MEDIALIB_PHOTO in the WMAppManifest.xml or you wont get any results.
Method 2:
The second option would be to use for example the WriteableBitmapEx library to create a thumbnail yourself, something along the lines of:
void task_Completed(object sender, Microsoft.Phone.Tasks.PhotoResult e)
{
if (e.TaskResult == Microsoft.Phone.Tasks.TaskResult.OK)
{
BitmapImage source = new BitmapImage();
source.SetSource(e.ChosenPhoto);
WriteableBitmap bitmap = new WriteableBitmap(source);
WriteableBitmap thumbnail = bitmap.Resize(100, 100, WriteableBitmapExtensions.Interpolation.Bilinear); // Creates a 100x100 thumbnail
}
}
Other methods:
Another solution might be using the Nokia Imaging SDK, which according to the documentation supports partial JPEG decoding (I haven't used this SDK myself so can't give you any example code right now though):
Using RAJPEG technology, access image data without decoding a whole
JPEG image for blazingly fast previews, application of effects,
rotation, and cropping of high resolution images.

Related

How to property remove (or keep) the background and contents when exporting PDF to PNG using Magic.NET-Q16-AnyCPU

https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf
First time trying the Magic.NET-Q16-AnyCPU and I encounter an issue that I think I just do know the correct method to use I hope someone could lead me to get this corrected. I have a pdf with some existing texts and tables, plus a redline text added by using a pdf editing software.
Attached picture #1: depends on which software I use to view the png, some software shows black background. I like to have the background can show white or show as transparent (which is preferred) for all software. With page containing the red line text, it shows the red line one correctly but the other contents.
Attached picture #2: If I use settings.UseMonochrome = true; then this is no longer an issue but the resulting image I get is not what I prefer. I may sound stupid but with settings.UseMonochrome = false; my eyes feel better, especially when there are some graphics and tables.
Can I set settings. UseMonochrome = false; and still get all the contents shown correctly? And can I ensure the PNG background is either removed or set as White? Already try the image.BackgroundColor = MagickColors.White; but this does not impact the result.
private void button1_Click(object sender, EventArgs e)
{
var settings = new MagickReadSettings();
settings.Density = new Density(100, 100);
//Do not want to use this
//settings.UseMonochrome = true;
var filename = #"C:\Users\USER1\Desktop\dummy.pdf";
using (var images = new MagickImageCollection())
{
if(System.IO.File.Exists(filename))
{
images.Read(filename, settings);
var page = 1;
foreach (var image in images)
{
image.Write("C:\\Users\\USER1\\Desktop\\dummy.PNG");
page++;
}
}
}
}

Loaded pictureBox.ImageLocation is null

I'm trying to do something when I click image displayed inside pictureBox1.
pictureBox is loaded with this code:
string imgpath = #"img\256.png";
pictureBox48.Image = Image.FromFile(imgpath);
Then control is released to me so I can see that the picture loaded correctly.
Then i click the picture:
public void pictureBox48_Click(object sender, EventArgs e)
{
string variable1 = pictureBox48.ImageLocation;
Form3 fo = new Form3(variable1);
fo.ShowDialog();
}
This doesn't work. When I debug the code I see that variable1 stay null, that is pictureBox48.ImageLocation is null. Why is that? Shouldn't it be the path to the image that is assigned there?
You can't get the image path when you set the image using the Image property because you are assigning an Image object which can come from different sources.
Set the image using ImageLocation.
string imgpath = #"img\256.png";
pictureBox48.ImageLocation = imgpath;
When you click in the PictureBox you can get the path using the same property:
public void pictureBox48_Click(object sender, EventArgs e)
{
string variable1 = pictureBox48.ImageLocation;
Form3 fo = new Form3(variable1);
fo.ShowDialog();
}
When dealing with Image or PictureBox I would recommend to not use something like Location or Path of the image. Assume that when the image is loaded user removes it from the hard drive and you're left with the code full of errors.
That's why you should rely on Image itself as it contains every information about the image like pixel format, width, height and raw pixel data.
I would recommend you to just copy the image, not the path to the file.
This piece of code should give you a hint:
pixtureBox48.Image = Image.FromFile(imgPath);
// above code assumes that the image is still on hard drive and is accessible,
// now let's assume user deletes that file. You have the data but not on the physical location.
Image copyImage = (Image)pictureBox48.Image.Clone();
Form3 fo = new Form(copyImage); // change .ctor definition to Form(Image copy)
fo.ShowDialog();

C# WPF display images like a grid

Im a total C#/programming beginner.
I try to display alot of pictures like an album or grid like.
It looks like this so far:
http://i.imgur.com/LC7lhXi.jpg
But there are empty places and when I scroll down it looks even worse: http://i.imgur.com/QuFOgr1.png
I created a UniformGrid inside a ScrollViewer. That was the easiest way for me to get what I want. Maybe not the best solution. If I add more pictures the images are getting smaller. I think thats cause of the uniform grid.
Here are two code example how I did that.
js.movie1 is an object which contains a few members. js.movie1[0].poster is the file name of the first picture (there are 275 pictures).
This object is created by the JSON.NET framework. It just reads a JSON file set some variables and I put the object in a list.
for example js.movie1[0].poster is the file name of the poster as a picture, js.movie1[0].title is the title of the movie and so on.
private void btnShow_Click(object sender, RoutedEventArgs e)
{
uGrid.Children.Clear();
string strWebAdress = #"https://image.tmdb.org/t/p/original/";
for (int i = 0; i < js.movie1.Count; i++)
{
Image img = new Image();
BitmapImage bimg = new BitmapImage(new Uri(strWebAdress + js.movie1[i].poster));
//bimg.sou
img.BeginInit();
img.Source = bimg;
img.EndInit();
uGrid.Children.Add(img);
}
Or I did this:
private void btnShow_Click(object sender, RoutedEventArgs e)
{
uGrid.Children.Clear();
string strWebAdress = #"https://image.tmdb.org/t/p/original/";
List<string> listImage = Directory.GetFiles(strPath, "*jpg").Select(System.IO.Path.GetFileName).ToList();
List<Image> imgList = new List<Image>();
for (int i = 0; i < js.movie1.Count; i++)
{
Image Controlimage = new Image
{
Source = new BitmapImage(new Uri(strCoverUrl + js.movie1[i].poster)),
};
uGrid.Children.Add(Controlimage);
}
My problem is that there are empty spaces between some pictures, I cant resize them like I want. And I want to scroll while the program is loading the pictures.
The program needs 1,5 GB of Ram and alot of CPU power so I need a betetr solution for this.
With Foreach I can scroll but I created a array for that. I dont know how to count in foreach with a object. Atleast not in the way my object is used.
There have to be a way to load and display pictures from an URL which doesnt block the UI and needs so much power.
Like I said Im a bloody beginner ;)
Greetings Fabian :)

Windows phone 8.1 image loading on UI

We are developing an app which have to attach an image at the runtime and display the same to the UI. We are using following set of code file for it:
private void Btn_Attach_File_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.FileTypeFilter.Add(".jpg");
fileOpenPicker.FileTypeFilter.Add(".jpeg");
fileOpenPicker.FileTypeFilter.Add(".png");
fileOpenPicker.ContinuationData["Operate"] = "OpenImage";
fileOpenPicker.PickSingleFileAndContinue();
}
Also, to continue the app after picking file from storage, here is the code :
public async void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs args)
{
if ((args.Files != null && args.Files.Count > 0))
{
IReadOnlyList<StorageFile> files = args.Files;
Image myImage = new Image();
foreach (StorageFile file in files)
{
if (args.ContinuationData["Operate"] as string == "OpenImage" && args.Files != null && args.Files.Count > 0)
{
IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
System.Diagnostics.Debug.WriteLine(file.Name);
System.Diagnostics.Debug.WriteLine(file.Path);
using (StorageItemThumbnail thumbnail = await file.GetThumbnailAsync(ThumbnailMode.SingleItem, 190)) //, ThumbnailOptions.UseCurrentScale);
{
if (thumbnail != null && thumbnail.Type == ThumbnailType.Image)
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(thumbnail);
myImage.Source = bitmapImage;
}
}
}
}
}
}
Above code is in xaml.cs file.
But the problem is, even though I'm loading the file, there is no attachment on UI.
Do we need to make any changes to the corresponding xaml file? we've searched a lot on it but couldn't find any solution.
Thanks in advance,
First, make an image control in xaml:
<Image Name="img"/>
In codebehind after the loop:
this.img.Source = myImage.Source;
//For better perf according to the docs, specify this
//this.img.Source.DecodePixelWidth = 200
Certainly it's possible to make a binding instead of using the Name property, but this is the easiest way.
Read the docs: MSDN
One other thing, the loop foreach (StorageFile file in files) isn't that useful if you have one file, and if you have more than one file it will take the last file.
Feel free to ask for more info!
Happy coding :)!

Adding a picture from a resource to a picture box

I got this issue with displaying a image that i allready have added as a resource. I am guessing i am missing something vital but i cant find what it is. I am hoping that someone has a better idea of what i am doing wrong atm.
I have added an .bmp image into the solutiontree and changed the build action properties of that image to Embedded resource but i cant figure out how to call that image from the pipe?
as the user clicks a button the image should be sent to the imagebox, the code i have written so far looks like this:
this is ofs only the button_click code:
private void button1_Click(object sender, EventArgs e)
{
//Show image in the picturebox of selected cake
Image image = Image.FromFile(fruitcake.jpg);
pictbox.Image = image;
pictbox.Height = 163;
pictbox.Width = 223;
choice = 1;
lblCookiesPerGram.Text = string.Empty;
}
Anyone has an idea of what i am doing wrong or can i do this in another war? mind thou its 4 buttons the user clicks and there is a image for each one ;)
//Regards
If you go to your Solution - Properties window and select the Resources tab and add the image through this manager, then the images can be directly referenced like this:
Image image = Properties.Resources.fruitcake;
To retrieve an image from a resource, you can do something like:
using (Stream imgStream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(
"MyNamespace.resources.fruitcake.jpg"))
{
var image = new Bitmap(imgStream);
pictBox.Image = image;
pictBox.Height = image.Height;
pictBox.Width = image.Width;
}

Categories