ObjectDisposedException when I try to use an Image source - c#

I need to add an Image to my Panel, so I use the following code:
var image = new Image();
var source = new BitmapImage();
source.BeginInit();
source.CacheOption = BitmapCacheOption.OnLoad;
source.StreamSource = new FileStream(filename, FileMode.Open);
source.EndInit();
// I close the StreamSource so I can load again the same file
source.StreamSource.Close();
image.Source = source;
The problem is that when I try to use my image source I get an ObjectDisposedException:
var source = ((BitmapImage)image.Source).StreamSource;
// When I use source I get the exception
using (var stream = new MemoryStream((int)(source.Length)))
{
source.Position = 0;
source.CopyTo(stream);
// ...
}
It happens because I closed the source, but if I don't close it I can't be able to load again the same file.
How can I solve this problem (i.e. close the source to be able to load the same file more than once, and to be able to use the source without get the exception)?

The following solution should work for you:
var image = new Image();
var source = new BitmapImage();
source.BeginInit();
source.CacheOption = BitmapCacheOption.OnLoad;
// Create a new stream without disposing it!
source.StreamSource = new MemoryStream();
using (var filestream = new FileStream(filename, FileMode.Open))
{
// Copy the file stream and set the position to 0
// or you will get a FileFormatException
filestream.CopyTo(source.StreamSource);
source.StreamSource.Position = 0;
}
source.EndInit();
image.Source = source;

Related

how to get header text with image from .DOCX file

i want to get header image form doc file. i use following code it gives me image path but i can't get it
DocumentFormat.OpenXml.Packaging.ImagePart img = header.ImageParts.FirstOrDefault();
string imgpath = img.Uri.OriginalString;
I think your approach didn't work because the doc file is a zip file.
I don't know in which format you need that image, but you can try something like this to retrieve an image object. I updated my answer with an working example hope it helps.
using (var document = WordprocessingDocument.Open("your document path", true))
{
//Get the header
var header = document.MainDocumentPart.HeaderParts.First();
//These are your paragraphs where you can get the headers Text from
var paragraphList = header.Header.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>();
//Get the imageId
string imgId = header.GetIdOfPart(header.ImageParts.First());
var imageSource=new BitmapImage();
//Get the imageStream
using (var imgStream = ((ImagePart)header.GetPartById(imgId)).GetStream())
{
//Copy stream to BitmapImage
using (var memoryStream = new MemoryStream())
{
imgStream.CopyTo(memoryStream);
memoryStream.Position = 0;
imageSource.BeginInit();
imageSource.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
imageSource.CacheOption = BitmapCacheOption.OnLoad;
imageSource.UriSource = null;
imageSource.StreamSource = memoryStream;
imageSource.EndInit();
}
imageSource.Freeze();
//Save BitmapImage to file
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imageSource));
using (var stream = new FileStream("your path for the image.png", FileMode.Create))
encoder.Save(stream);
}
}
and this is an example how you can get position of your picture, but keep in mind it will only work if your picture got an absolute position.
List<DocumentFormat.OpenXml.Wordprocessing.Drawing> sdtElementDrawing =
header.Header.Descendants<DocumentFormat.OpenXml.Wordprocessing.Drawing>().ToList();
var distL= sdtElementDrawing.First().Anchor.DistanceFromLeft;

how to rotate image in File in C# & WPF application

I have WPF and C# application. which captures the images and Save in to file(*.jpg).
I have the image path and i want to rotate image saved in File through the c# code.
and Save the Rotated image in same file.
How can i do that?
Use the rotate flip method.
E.g.:
Bitmap bitmap1 = (Bitmap)Bitmap.FromFile(#"C:\test.jpg");
bitmap1.RotateFlip(RotateFlipType.Rotate180FlipNone);
bitmap1.Save(#"C:\Users\Public\Documents\test rotated.jpg");
you can use my method:
BitmapImage rotateImage(string filename,int angle)
{
WIA.ImageFile img = new WIA.ImageFile();
img.LoadFile(filename);
WIA.ImageProcess IP = new WIA.ImageProcess();
Object ix1 = (Object)"RotateFlip";
WIA.FilterInfo fi1 = IP.FilterInfos.get_Item(ref ix1);
IP.Filters.Add(fi1.FilterID, 0);
Object p1 = (Object)"RotationAngle";
Object pv1 = (Object)angle;
IP.Filters[1].Properties.get_Item(ref p1).set_Value(ref pv1);
img = IP.Apply(img);
File.Delete(filename);
img.SaveFile(filename);
BitmapImage imagetemp = new BitmapImage();
using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
imagetemp.BeginInit();
imagetemp.CacheOption = BitmapCacheOption.OnLoad;
imagetemp.StreamSource = stream;
imagetemp.EndInit();
}
return imagetemp;
}
usage:
string filename = System.AppDomain.CurrentDomain.BaseDirectory + "4.jpg";
image.Source = rotateImage(filename,90);

How to read image dimensions at C# wpf - there is no dispose method for BitmapImage

With the way below i am able to read.
But there is no dispose method so i am not able to delete the file later.
So the below method is getting failed.
I could not come up with a proper solution.
Bitmap class is not recognized in C# 4.5 WPF application.
thank you
DirectoryInfo dInfo = new DirectoryInfo(#"C:\pokemon_files\images\");
FileInfo[] subFiles = dInfo.GetFiles();
BitmapImage myImg;
foreach (var vrImage in subFiles)
{
string srFilePath = vrImage.FullName;
System.Uri myUri = new Uri(srFilePath);
myImg = new BitmapImage(myUri);
if (myImg.Width < 50)
{
File.Delete(srFilePath);
continue;
}
}
I assume the error you get is caused by trying to delete the file which is currently in use
by the bitmap (I don't remember the exception name).
There is a solution to that, that is: making a byte stream.
byte[] imageData;
using(var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using(var binaryReader = new BinaryReader(fileStream))
{
imageData = binaryReader.ReadBytes((int)fileStream.Length);
}
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = new MemoryStream(imageData);
bitmap.EndInit();
//Now you can check the width & height, the file stream should be closed so you can
//delete the file.
[EDIT]
If you don't want to read the bytes by BinaryReader, there's always this solution if you want to read all bytes from the file.

Adding Image to FixedPage in WPF

I want to be able to print images with other UIElements. I have a FixedPage instance and trying to add image like so
// Basic printing stuff
var printDialog = new PrintDialog();
var fixedDocument = new FixedDocument();
fixedDocument.DocumentPaginator.PageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
FixedPage page = new FixedPage();
page.Width = fixedDocument.DocumentPaginator.PageSize.Width;
page.Height = fixedDocument.DocumentPaginator.PageSize.Height;
Image img = new Image();
// PrintIt my project's name, Img folder
var uriImageSource = new Uri(#"/PrintIt;component/Img/Stuff.png", UriKind.RelativeOrAbsolute);
img.Source = new BitmapImage(uriImageSource);
img.Width = 100;
img.Height = 100;
page.Children.Add(img);
PageContent pageContent = new PageContent();
((IAddChild)pageContent).AddChild(page);
fixedDocument.Pages.Add(pageContent);
// Print me an image please!
_printDialog.PrintDocument(fixedDocument.DocumentPaginator, "Print");
It gives me a blank paper. I'm wondering why, because other UIElements (such as TextBox, Grid, Rect) appear with no problems. What am I missing?
Thanks!
PS OK, I've found another solution. I don't know why but with that Uri a picture loads properly
var uri = new Uri("pack://application:,,,/Img/Stuff.png");
To be more clear on my Code
var bitImage = new BitmapImage();
bitImage.BeginInit();
bitImage.StreamSource = new FileStream(fileName, FileMode.Open, FileAccess.Read);
bitImage.DecodePixelWidth = 250;
bitImage.CacheOption = BitmapCacheOption.OnLoad;
bitImage.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
bitImage.EndInit();
bitImage.StreamSource.Seek(0, System.IO.SeekOrigin.Begin);
bitImage.Freeze();
var tempImage = new Image {Source = bitImage};
var imageObject = new ImageObject(tempImage, fileName);
bitImage.StreamSource.Dispose();
page.Children.Add(imageObject);
First i would like to suggest that, see below.
Set the sourceStream of the Image for BitMap
bitImage.StreamSource = new FileStream(fileName, FileMode.Open, FileAccess.Read);
Then freeze the BitMap Image, or it ll not be in the instance as render able image.
bitImage.StreamSource.Seek(0, System.IO.SeekOrigin.Begin);
bitImage.Freeze();
This should work, if not i personally think it is a bad idea to directly work with BitMaps, i use Bitmap to create image form file then copy it to the type Image(system.drawing iguess), something like below
var tempImage = new Image {Source = bitImage};
var imageObject = new ImageObject(tempImage, fileName);
bitImage.StreamSource.Dispose();
this tempImage can be added to ur page as regular UIElement.
Hope it helps.

Delete Image in WPF JpegBitmapDecoder

I am using
File.Delete("new13.jpg");
FileStream stream1 = new FileStream("new13.jpg", FileMode.Create);
JpegBitmapEncoder encoder1 = new JpegBitmapEncoder();
encoder1.FlipHorizontal = true;
encoder1.FlipVertical = false;
encoder1.QualityLevel = 30;
//encoder.Rotation = Rotation.Rotate90;
encoder1.Frames.Add(BitmapFrame.Create(bitmap));
encoder1.Save(stream1);
when my camera takes a new picture it is stored as "new13.jpg" but when i again take picture it shows exception that this image it is being used by another process . I am doing some image processing on image after being taken. How do i get rid of this exception .
You should close the stream after saving to it:
encoder1.Save(stream1);
stream1.Close();
Or better use a using block like this:
using (FileStream stream = new FileStream("new13.jpg", FileMode.Create))
{
encoder1.Save(stream);
}

Categories

Resources