Cannot get the string result from image C# Windows Form - c#

It's always stop at the end of RawFormat, what did I do wrong?
private void genImgBtn_Click(object sender, EventArgs e)
{
if (pictureBox1.Image != null)
{
Image gambar = pictureBox1.Image;
using (MemoryStream ms = new MemoryStream())
{
gambar.Save(ms,gambar.RawFormat);
byte[] imageBytes = ms.ToArray();
qrtext.Text = Convert.ToBase64String(imageBytes);
}
}
else
{
MessageBox.Show("Silahkan pilih gambar terlebih dahulu");
}
}
The program stops and asks for not giving null value. I don't know what should I do to resolve this.

Related

C# how to use variable outside of block of code

I have the following code. I want to use pictureBox1.Image = image outside of the code block like so:
private void button1_Click(object sender, EventArgs e) {
using(MemoryStream memoryStream = new MemoryStream()) {
pic.Image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] imageBytes = memoryStream.ToArray();
}
Image image = Image.FromStream(memoryStream);
pictureBox1.Image = image;
}
I get the folloowing error: The name 'memoryStream' does not exist in the current context. I know I can do the following move the last 2 lines into the brackets and the code works but How can I use variable outside of the { } block of code
I know the code below works but i just want to know if there is a way to use pictureBox1.Image = image outside of the block of code.
private void button1_Click(object sender, EventArgs e)
{
using(MemoryStream memoryStream = new MemoryStream())
{
pic.Image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] imageBytes = memoryStream.ToArray();
Image image = Image.FromStream(memoryStream);
pictureBox1.Image = image;
}
}
You can't and shouldn't use the stream outside of the using scope, after that it will get disposed and you don't run into leaking issues.
You could just assign the value after the scope, when you declare the variable before it.
private void button1_Click(object sender, EventArgs e)
{
Image image;
using(MemoryStream memoryStream = new MemoryStream())
{
pic.Image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
// byte[] imageBytes = memoryStream.ToArray(); //unused?
image = Image.FromStream(memoryStream);
}
pictureBox1.Image = image;
}
Or better yet make a function to read the image and return it.
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Image = readImage();
}
private Image readImage()
{
using(MemoryStream memoryStream = new MemoryStream())
{
pic.Image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
// byte[] imageBytes = memoryStream.ToArray(); //unused?
return Image.FromStream(memoryStream);
}
}
There's no problem putting that line outside the using block. The problem is line before. You can't use memoryStream outside the using block. The whole point of the using block is to create a scope for that variable and ensure that the object assigned to it is disposed at the end of the block. You can do this:
private void button1_Click(object sender, EventArgs e) {
Image image;
using(MemoryStream memoryStream = new MemoryStream()) {
pic.Image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] imageBytes = memoryStream.ToArray();
image = Image.FromStream(memoryStream);
}
pictureBox1.Image = image;
}
You can define MemoryStream outside the code block:
MemoryStream memoryStream = new MemoryStream();
using (memoryStream)
{
pic.Image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] imageBytes = memoryStream.ToArray();
}
Image image = Image.FromStream(memoryStream);
pictureBox1.Image = image;
Edit:(just for test)
If you think using releases all resources for the variable defined outside, test the following code:
MemoryStream memoryStream = new MemoryStream();
using (memoryStream)
{
byte[] messageBytes = Encoding.ASCII.GetBytes("test Massage");
memoryStream.Write(messageBytes, 0, messageBytes.Length);
}
var data = Encoding.Default.GetString(memoryStream.ToArray()); // data = "test Massage"

C# byte array to image not working with identical byte arrays

The complete code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Display byte array as image
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
Image img = ByteArrayToImage(File.ReadAllBytes("")); //fill with path info
pictureBox1.Image = (Image)img.Clone();
}
//Convert to image from bytes
public Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
ms.Position = 0;
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
//Open Image for conversion
private void loadImage_Click(object sender, EventArgs e)
{
OpenFileDialog opf = new OpenFileDialog();
DialogResult dr = new DialogResult();
dr = opf.ShowDialog();
if (dr == DialogResult.OK)
{
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = Image.FromFile(opf.FileName);
}
}
private void convertImage_Click(object sender, EventArgs e)
{
//Choose Path to Save To
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Title = "Choose Directory and File Name";
saveDialog.Filter = "Canga Comix *.CCMX|*.CCMX";
DialogResult dr = saveDialog.ShowDialog();
if (dr == DialogResult.OK)
{
byte[] array;
//Save Image
using (MemoryStream ms = new MemoryStream())
{
Image img = pictureBox1.Image;
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
array = ms.ToArray();
}
using(FileStream fs = new FileStream(saveDialog.FileName, FileMode.Create))
{
fs.Write(array, 0, array.Length);
}
}
}
//clear image
private void clearImage_Click(object sender, EventArgs e)
{
pictureBox1.Image = null;
}
}
}
These are pretty standard. I have a test program that uses these methods. It opens an image in a pictureBox and then converts it to byte[] and clears the pictureBox Image. Then you can hit Load byte[] and it will display the picture properly as it runs the ByteArrayToImage method.
Then if I save out a picture from my other program and try to open it in the test program it gives me the unholy "Parameter is not valid" error. Even though both text documents are exactly the same as far as I can tell.
This code contains a common problem. Here you create an Image bound to a stream containing your bitmap...
public Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
ms.Position = 0;
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
... and the using block disposes the MemoryStream instance on the way out, which makes the Image rather useless.
You can get an Image that manages its own memory instead of expecting your stream to stick around by calling Clone():
public Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
using (Image returnImage = Image.FromStream(ms))
{
return returnImage.Clone();
}
}
The clone isn't bound to the original stream.

WP8 e.ChosenPhoto to Base64 String

I have a Windows Phone 8 Application where I am taking a picture. I would like to get the Base64 String from the e.ChosenPhoto object but not sure how to go about it.
Code:
private void cameraCaptureTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
var bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
imgPhoto.Source = bmp;
imgPhoto.Stretch = Stretch.Uniform;
// Get the base64 String from the e.ChosenPhoto or the bmp object
}
}
The following is how I solved the issue:
byte[] bytearray = null;
using (var ms = new MemoryStream())
{
if (imgPhoto.Source != null)
{
var wbitmp = new WriteableBitmap((BitmapImage) imgPhoto.Source);
wbitmp.SaveJpeg(ms, 46, 38, 0, 100);
bytearray = ms.ToArray();
}
}
if (bytearray != null)
{
Sighting.Instance.ImageData = Convert.ToBase64String(bytearray);
PhotoModel.Instance.BitmapImage = bitmapImage;
}

upload image and save file stream in View State

protected void upload_Click(object sender, EventArgs e)
{
if (Upload.Value !="")
{
System.IO.Stream fs = Upload.PostedFile.InputStream;
img_uploadStream = Upload.PostedFile.InputStream;
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
Byte[] bytes = CreateThumbnail(br.ReadBytes((Int32)fs.Length),150);
string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
imageField.Src = String.Format("data:{0};base64,{1}", "image/jpeg", base64String);
}
}
After upload the image , Upload.PostedFile.InputStream has set to null value .
I want to save this Input Stream to asp.net View State to reuse .
You can use this code
public Byte[] YourImage
{
get
{
if(ViewState["Key"] != null)
{
return (Byte[]) ViewState["Key"];
}
return null;
}
set
{
ViewState["Key"] = value;
}
}
Set ViewState inside upload_Click:
ViewState["ImageStream"]=Upload.PostedFile.InputStream;
Then you can get your viewstate anywhere within the page where you want to use:
System.IO.Stream fstream=(System.IO.Stream)ViewState["ImageStream"];

Update WPF Image issue under SIlverlight 4.0

When my page loads and I press button1 I can get the image and can see it.
But when I click it second time it doesn't work at all. I debugged it button1_Click(...) and I am sure that imageData != null.
I really can't figure out what's up... Please help me!
private void button1_Click(object button, RoutedEventArgs e)
{
Guid sid = Guid.Parse("087462df-e4b6-484c-879e-cccc37b4c1f4");
EntityQuery<Screenshot> screen = this._myDomainContext.GetScreenshotQuery(sid);
this._myDomainContext.Load(screen).Completed += (sender, args) =>
{
try
{
byte[] imageData = (((LoadOperation<Screenshot>)sender).Entities.FirstOrDefault()).Screen;
if (imageData != null)
{
BitmapImage img = Utilities.Graphics.GetImage(imageData);
img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image1.Source = null;
image1.Source = img;
}
}
catch
{
}
};
}
and
public static BitmapImage GetImage(byte[] rawImageBytes)
{
BitmapImage imageSource = null;
try
{
using (MemoryStream stream = new MemoryStream(rawImageBytes))
{
stream.Seek(0, SeekOrigin.Begin);
BitmapImage b = new BitmapImage();
b.SetSource(stream);
imageSource = b;
}
}
catch
{
}
return imageSource;
}
Try changing the overload of Load:
this._myDomainContext.Load(screen, LoadBehavior.RefreshCurrent, true).Completed+= ...
I'm not completely sure on the cause if your issue, but I have a few pointers on the code with regards to using BitmapImage's.
There is no need to set the image1.Source property to null before assigning it with an actual source.
Don't dispose the stream you pass to the BitmapImage in case the control is trying to read from it.
I personally make use of BeginInit(...), StreamSource and EndInit(...) when working with BitmapImage's.

Categories

Resources