I made a QR-Code Encoder (WPF, c#) by using ZXing.net
I am displaying the QR-Code in an Image-Control
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new ZXing.Common.EncodingOptions
{
Height = 200,
Width = 200,
Margin = 0
}
};
var image = writer.Write(qrtext.Text);
qrImg.Source = image;
After that I want to save the image. I was using this example Save Image in a Folder.
private void btnSaveImg_Click(object sender, RoutedEventArgs e)
{
string filePath = #"C:\Users\xxx\Desktop\image.png";
SaveToPng(qrImg, filePath);
}
void SaveToBmp(FrameworkElement visual, string fileName)
{
var encoder = new BmpBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
void SaveToPng(FrameworkElement visual, string fileName)
{
var encoder = new PngBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
// and so on for other encoders (if you want)
void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(visual);
BitmapFrame frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = File.Create(fileName))
{
encoder.Save(stream);
}
}
Unfortunately the image is not being saved. Furthermore, I get no exception. Hope you see my mistake.
Thx a lot
I found another solution, based on this post: How can I save the picture on image control in wpf?
So my solution, that works for me, is:
String filePath = #"C:\Users\xxx\Desktop\test.jpg";
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)qrImg.Source));
using (FileStream stream = new FileStream(filePath, FileMode.Create))
encoder.Save(stream);
Related
My code currently looks like this:
if (fe == "CR2")
{
Image img = null;
byte[] ba = File.ReadAllBytes(open.FileName);
using (Image raw = Image.FromStream(new MemoryStream(ba)))
{
img = raw;
}
Bitmap bm = new Bitmap(img);
pictureBox1.Image = bm;
statusl.Text = fe;
}
When I open a RAW image the program stops and Visual Studio says:
Parameter is not valid: Image raw = Image.FromStream(new MemoryStream(ba))
Please help! How can I get a RAW file to show in a PictureBox ?
Create the bitmap like this:
Bitmap bmp = (Bitmap) Image.FromFile(open.FileName);
or without using bitmap:
this.pictureBox1.Image = Image.FromFile(open.FileName);
Example WPF:
BitmapDecoder bmpDec = BitmapDecoder.Create(new Uri(origFile),
BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
BitmapEncoder bmpEnc = new BmpBitmapEncoder();
bmpEnc.Frames.Add(bmpDec.Frames[0]);
Stream ms = new MemoryStream();
bmpEnc.Save(ms);
Image srcImage = Bitmap.FromStream(ms);
You're actually disposing an Image by specifying using (Image raw = Image.FromStream(new MemoryStream(ba))) later assigning the Disposed instance of image to picturebox which leads to this exception. To make to work you've to either don't dispose or clone the image.
Bitmap raw = Image.FromStream(new MemoryStream(ba) as Bitmap;
pictureBox1.Image = raw;
Or simply Clone
using (Image raw = Image.FromStream(new MemoryStream(ba)))
{
img = raw.Clone() as Bitmap;
}
Both of the above should work
you try this code :
private static void SaveImageToRawFile(string strDeviceName, Byte[] Image, int nImageSize)
{
string strFileName = strDeviceName;
strFileName += ".raw";
FileStream vFileStream = new FileStream(strFileName, FileMode.Create);
BinaryWriter vBinaryWriter = new BinaryWriter(vFileStream);
for (int vIndex = 0; vIndex < nImageSize; vIndex++)
{
vBinaryWriter.Write((byte)Image[vIndex]);
}
vBinaryWriter.Close();
vFileStream.Close();
}
private static void LoadRawFile(string strDeviceName, out Byte[] Buffer)
{
FileStream vFileStream = new FileStream(strDeviceName, FileMode.Open);
BinaryReader vBinaryReader = new BinaryReader(vFileStream);
Buffer = new Byte[vFileStream.Length];
Buffer = vBinaryReader.ReadBytes(Convert.ToInt32(vFileStream.Length));
vBinaryReader.Close();
vFileStream.Close();
}
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)
I have some set of TIFF files (8-bit palette). I need to change the bit depth into 32 bit.
I tried the code below, but getting an error, that the parameter is not correct... Could you help me to fix it? Or maybe some1 is able to suggest some different solution for my problem.
public static class TiffConverter
{
public static void Convert8To32Bit(string fileName)
{
BitmapSource bitmapSource;
using (Stream imageStreamSource = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
bitmapSource = decoder.Frames[0];
}
using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate))
{
ImageCodecInfo tiffCodec = ImageCodecInfo.GetImageEncoders().FirstOrDefault(codec => codec.FormatID.Equals(ImageFormat.Tiff.Guid));
if (tiffCodec != null)
{
Image image = BitmapFromSource(bitmapSource);
EncoderParameters parameters = new EncoderParameters();
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 32);
image.Save(stream, tiffCodec, parameters);
}
}
}
private static Bitmap BitmapFromSource(BitmapSource bitmapSource)
{
Bitmap bitmap;
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapSource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
}
Thanks in advance!
[edit]
I noticed that the error appears in this line:
image.Save(stream, tiffCodec, parameters);
ArgumentException occured: Parameter is not valid.
If the error you're getting is on the line:
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 32);
then the problem is that the compiler cannot know if you're referring System.Text.Encoder or System.Drawing.Imaging.Encoder...
Your code should look like this to to avoid any ambiguity:
parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 32);
Edit:
This is an alternative (and tested :)) way of doing the same thing:
Image inputImg = Image.FromFile("input.tif");
var outputImg = new Bitmap(inputImg.Width, inputImg.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (var gr = Graphics.FromImage(outputImg))
gr.DrawImage(inputImg, new Rectangle(0, 0, inputImg.Width, inputImg.Height));
outputImg.Save("output.tif", ImageFormat.Tiff);
I have a Image (Frameworkelement) on my GUI.
There is a image in there. Now I'm performing a doubleclick at this image and I want, that
the Image saves itself and is going to be opened, with the default imageviewer.
My Code:
void image_MouseDown(object sender, MouseButtonEventArgs e)
{
//Wayaround, cause there is no DoubleClick Event on Image
if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2)
{
SaveToPng(((Image)sender), "SavedPicture.png");
Process.Start("SavedPicture.png");
}
}
void SaveToPng(FrameworkElement visual, string fileName)
{
var encoder = new PngBitmapEncoder();
SaveUsingEncoder(visual, fileName, encoder);
}
void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
RenderTargetBitmap bitmap = new RenderTargetBitmap(
(int)visual.ActualWidth,
(int)visual.ActualHeight,
96,
96,
PixelFormats.Pbgra32);
bitmap.Render(visual);
BitmapFrame frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = File.Create(fileName))
{
encoder.Save(stream);
}
}
Opening the picture works fine with Process.Start. The problem is the saving, well it saves the picture: SavedPicture.png but, Its just black, so theres no graphic.. Maybe someone could tell me, whats wrong in my code or knows a better way of saving a image in WPF.
It is necessary that the image is displayed before it is saved. So, if you want to use RenderTargetBitmap just set the Image.Source and load the Image before saving with SaveToPng (ActualWidth and ActualHeight must not be null).
Example:
If you have the Image inside a Panel:
<Grid x:Name="MyGrid">
<Image x:Name="MyImage"/>
</Grid>
I set Image.Source in my test class constructor, and only after the image was loaded i save it:
public MainWindow()
{
InitializeComponent();
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri("image.png", UriKind.RelativeOrAbsolute);
bmp.EndInit();
MyImage.Source = bmp;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
RenderTargetBitmap bmp = new RenderTargetBitmap((int)MyGrid.ActualWidth,
(int)MyGrid.ActualHeight, 96, 96, PixelFormats.Default);
bmp.Render(MyImage);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (var stream = System.IO.File.Create("newimage.png"))
{ encoder.Save(stream); }
}
If you don't want to use Grid ActualWidth and ActualHeight just pass your with and height as arguments.
Depends on the type of the Image.Source, assuming that you have a BitmapSource as in the article it should be along those lines:
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)image.Source));
using (FileStream stream = new FileStream(filePath, FileMode.Create))
encoder.Save(stream);
by the way RenderTargetBitmap class is to Converts a Visual object into a bitmap. its recommended by the team
sample
http://msdn.microsoft.com/en-us/library/aa969819.aspx
Problem solved.
I used this: File.WriteAllBytes()
to save the image from binaryformat
I am looking to create a function that takes a BitmapImage and saves it as a JPEG on the local Windows Phone 7 device in isolated storage:
static public void saveImageLocally(string barcode, BitmapImage anImage)
{
// save anImage as a JPEG on the device here
}
How do I accomplish this? I'm assuming I used IsolatedStorageFile somehow?
Thanks.
EDIT:
Here is what I have found so far... can anyone confirm if this is the correct way to do this?
static public void saveImageLocally(string barcode, BitmapImage anImage)
{
WriteableBitmap wb = new WriteableBitmap(anImage);
using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var fs = isf.CreateFile(barcode + ".jpg"))
{
wb.SaveJpeg(fs, wb.PixelWidth, wb.PixelHeight, 0, 100);
}
}
}
static public void deleteImageLocally(string barcode)
{
using (IsolatedStorageFile MyStore = IsolatedStorageFile.GetUserStoreForApplication())
{
MyStore.DeleteFile(barcode + ".jpg");
}
}
static public BitmapImage getImageWithBarcode(string barcode)
{
BitmapImage bi = new BitmapImage();
using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var fs = isf.OpenFile(barcode + ".jpg", FileMode.Open))
{
bi.SetSource(fs);
}
}
return bi;
}
To save it:
var bmp = new WriteableBitmap(bitmapImage);
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = storage.CreateFile(#"MyFolder\file.jpg"))
{
bmp.SaveJpeg(stream, 200, 100, 0, 95);
stream.Close();
}
}
Yes, the stuff you added in your edit is exactly what I have done before :) it works.
This is my code but you can take the neccesary points from there:
var fileName = String.Format("{0:}.jpg", DateTime.Now.Ticks);
WriteableBitmap bmpCurrentScreenImage = new WriteableBitmap(480, 552);
bmpCurrentScreenImage.Render(yourCanvas, new MatrixTransform());
bmpCurrentScreenImage.Invalidate();
SaveToMediaLibrary(bmpCurrentScreenImage, fileName, 100);
public void SaveToMediaLibrary(WriteableBitmap bitmap, string name, int quality)
{
using (var stream = new MemoryStream())
{
// Save the picture to the Windows Phone media library.
bitmap.SaveJpeg(stream, bitmap.PixelWidth, bitmap.PixelHeight, 0, quality);
stream.Seek(0, SeekOrigin.Begin);
new MediaLibrary().SavePicture(name, stream);
}
}