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);
}
Related
I'm developing a Windows Forms application where one of the things i need to do is, extract the image from .img file. I'm being able to read the normal jpg and png files, but not .img file.
I could not find much information on internet regarding this. I did find some code on msdn and i tried to get it to work. Below is the code and exception that is being thrown.
FileInfo file = new FileInfo(FilePath.Text);
FileStream f1 = new FileStream(FilePath.Text, FileMode.Open,
FileAccess.Read, FileShare.Read);
byte[] BytesOfPic = new byte[Convert.ToInt32(file.Length)];
f1.Read(BytesOfPic, 0, Convert.ToInt32(file.Length));
MemoryStream mStream = new MemoryStream();
mStream.Write(BytesOfPic, 0, Convert.ToInt32(BytesOfPic.Length));
Bitmap bm = new Bitmap(mStream, false);
mStream.Dispose();
// ImageBox is name of a PictureBox
ImageBox.image = bm; // this line is throwing the error
Exception caught
System.ArgumentException: Parameter is not valid.
at System.Drawing.Bitmap..ctor(Stream stream, Boolean useIcm)
at A02_Stegnography.Form1.ReadImgFile() in C:\Users\tiwar\Desktop\A02-Stegnography\A02-Stegnography\Form1.cs:line 65
I'm sorry if this is a stupid question. I hope i have provided enough information but if i haven't please let me know.
FileInfo file = new FileInfo(FilePath.Text);
FileStream f1 = new FileStream(FilePath.Text, FileMode.Open,
FileAccess.Read, FileShare.Read);
byte[] BytesOfPic = new byte[Convert.ToInt32(file.Length)];
f1.Read(BytesOfPic, 0, Convert.ToInt32(file.Length));
using (MemoryStream mStream = new MemoryStream())
{
mStream.Write(BytesOfPic, 0, BytesOfPic.Length);
mStream.Seek(0, SeekOrigin.Begin);
Bitmap bm = new Bitmap(mStream);
// ImageBox is name of a PictureBox
ImageBox.image = bm;
}
You can try my solution for problem
I need to convert a byte[] to an Image, but I cannot make it work in C#. If I save the bytearray to a file like this:
using (System.IO.FileStream fs = System.IO.File.Create("test.jpg"))
{
fs.Write(bytearray, 0, (int)lenght);
fs.Close();
}
And test.jpg shows properly. But when I try to make Image from the bytearray like this:
MemoryStream ms = new MemoryStream(bytearray);
pictureBox1.Image = Image.FromStream(ms);
It shows only black box.
I guess one problem is since you are creating test.jpg, it doesn't have any data and so the bytearray is empty.
Do something like :-
byte[] fileData = null;
using (var fs = new FileStream("C:\\1\\roses.jpg", FileMode.Open, FileAccess.Read))
{
var totalLength = (int)fs.Length;
using (var binaryReader = new BinaryReader(fs))
{
fileData = new byte[totalLength];
fs.Read(fileData, 0, totalLength);
fs.Close();
}
MemoryStream ms = new MemoryStream(fileData);
pictureBox1.Image = Image.FromStream(ms);
}
Okay, all was my bad. The code is correct, but the reason why it was showing only black screen was, becuase the picture was so big and it was black in the corners. And the pictureBox was not resizing it or anything so it showed its top right corner only.
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;
According to the image encoding example here I should be able to use JpegBitmapEncoder to encode an image for saving as a jpeg file but get this compile error:
error CS1503: Argument 1: cannot convert from 'System.Windows.Controls.Image' to 'System.Uri'
I don't see a way (property or method in Image) to get System.Uri from Image.
What am I missing?
The Image xaml code is
<Image Name="ColorImage"/>
The SaveImage C# is
...
SaveImage(ColorImage, path);
...
private void SaveImage(Image image, string path)
{
var jpegEncoder = new JpegBitmapEncoder();
jpegEncoder.Frames.Add(BitmapFrame.Create(image));
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
jpegEncoder.Save(fs);
}
}
The code below (taken mostly from the kinect-sdk) streams 640 x 480 RBG to a WriteableBitmap at 30 Fps (the kinect ColorImageFormat is RgbResolution640x480Fps30).
using (var colorImageFrame = allFramesReadyEventArgs.OpenColorImageFrame())
{
if (colorImageFrame == null) return;
var haveNewFormat = currentColorImageFormat != colorImageFrame.Format;
if (haveNewFormat)
{
currentColorImageFormat = colorImageFrame.Format;
colorImageData = new byte[colorImageFrame.PixelDataLength];
colorImageWritableBitmap = new WriteableBitmap(
colorImageFrame.Width,
colorImageFrame.Height, 96, 96, PixelFormats.Bgr32, null);
ColorImage.Source = colorImageWritableBitmap;
}
// Make a copy of the color frame for displaying.
colorImageFrame.CopyPixelDataTo(colorImageData);
colorImageWritableBitmap.WritePixels(
new Int32Rect(0, 0, colorImageFrame.Width, colorImageFrame.Height),
colorImageData,
colorImageFrame.Width*Bgr32BytesPerPixel,
0);
}
private void SaveImage(string path)
{
var jpegEncoder = new JpegBitmapEncoder();
jpegEncoder.Frames.Add(BitmapFrame.Create(colorImageWritableBitmap));
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
jpegEncoder.Save(fs);
}
}
The problem occurs, because you pass an Image to BitmapFrame.Create. Imageis more common in Windows Forms. A simple approach would be to create a MemoryStream first and the pass this:
private void SaveImage(Image image, string path)
{
MemoryStream ms = new MemoryStream();
image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
var jpegEncoder = new JpegBitmapEncoder();
jpegEncoder.Frames.Add(BitmapFrame.Create(ms));
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
jpegEncoder.Save(fs);
}
}
Addition (see conversation in comments):
you could try to use the CopyPixels method on the writeableBitmap object and copy the pixels to a byte array which you load to a MemoryStream and the write it to a Jpeg File withe the JpegBitmapEncoder. But it's just a guess.
This could work, too:
private void SaveImage (WriteableBitmap img, string path)
{
FileStream stream = new FileStream(path, FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(img));
encoder.Save(stream);
stream.Close();
}
You will just have to extract the WriteableBitmap from your Image control
Try: BitmapFrame.Create(image.Source)
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.