I am using WPF to insert an image to my MySQL database. I can upload the file to image control but I don't know how to save it.
Here is what I've done so far. The emp_image is the image control that displays the photo.
private void btn_save_image_click(object sender,...)
{
Mysqlconnection cn= new mysqlconnection(connectionstring);
byte[] imagedata;
imagedata=File.ReadAllBytes(emp_img); //..here is error,it says has invalid arguments..//
mysqlcommand= new mysqlcommand("insert into dep_table(photo)values(?data)",cn);
cmd.parameters.addwithvalue("?data", imagedata);
cn.open();
cmd.executeNonQuery();
cn.close();
}
you need to convert the image source to byte[] :
public static byte[] ImageToArray(BitmapSource image)
{
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return stream.ToArray();
}
}
Then, call the function:
imagedata = ImageToArray((BitmapSource)emp_img.Source);
Seems you are not passing the file path.
Please check File::ReadAllBytes Method
Should be something like
var imagedata=File.ReadAllBytes(filepath);
Related
When I try to read images from my SQL Server database I get an error: on the following line:
Image returnImage = Image.FromStream(ms);
An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Parameter is not valid.
My code:
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
private ArrayList GetImagesFromDB(string code)
{
ArrayList images = new ArrayList();
SqlCommand selectImagesCommand = new SqlCommand("SELECT * FROM images WHERE code = '"+code+"'");
selectImagesCommand.Connection = myConnection;
if(myConnection.State == ConnectionState.Closed){
myConnection.Open();
}
SqlDataReader imagesReader = selectImagesCommand.ExecuteReader();
while (imagesReader.Read())
{
byte[] newimagebytesRecord = (byte[])imagesReader["image"];
images.Add(byteArrayToImage(newimagebytesRecord));
}
return images;
}
Use SqlDataReader.GetStream method.
So you would do something along the lines:
using(SqlDataReader imageReader = selectSingleImageCommand.ExecuteReader(CommandBehavior.SequentialAccess))
{
if (imageReader.Read())
{
using (Stream backendStream = imageReader.GetStream(0))
{
//Do whater you need with the Stream
}
}
}
You migh also be able to iterate over the reader (selecting multiple images) and open stream by stream - I haven't use it that way though, so I'm not 100% sure.
try
{
SqlCommand cmdSelect=new SqlCommand("select Picture" +
" from tblImgData where ID=#ID",this.sqlConnection1);
cmdSelect.Parameters.Add("#ID",SqlDbType.Int,4);
cmdSelect.Parameters["#ID"].Value=this.editID.Text;
this.sqlConnection1.Open();
byte[] barrImg=(byte[])cmdSelect.ExecuteScalar();
string strfn=Convert.ToString(DateTime.Now.ToFileTime());
FileStream fs=new FileStream(strfn,
FileMode.CreateNew, FileAccess.Write);
fs.Write(barrImg,0,barrImg.Length);
fs.Flush();
fs.Close();
pictureBox1.Image=Image.FromFile(strfn);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
this.sqlConnection1.Close();
}
So I've got this image in the shape of a byte[] that I want to display in my view.
This is my model of the image:
public class ImageModel
{
public Byte[] imageFirst { get; set; }
}
This is my controller picking out the image from a db:
public ActionResult Image()
{
string cs = "Data Source=" + Environment.CurrentDirectory + "\\ImageDB.db";
using (SQLiteConnection con = new SQLiteConnection(cs))
{
var listOfImages = new List<ImageModel>();
string stm = "SELECT * FROM Image";
con.Open();
using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
listOfImages.Add(new ImageModel
{
imageFirst = Serialize(rdr["image_first"]),
});
}
rdr.Close();
Images = listOfImages;
}
}
con.Close();
}
return View(Images);
}
public static byte[] Serialize(object obj)
{
var binaryFormatter = new BinaryFormatter();
var ms = new MemoryStream();
binaryFormatter.Serialize(ms, obj);
return ms.ToArray();
}
And this is when I try to show the image in the view:
<img src="data:image/jpg;base64,#(Convert.ToBase64String(#item.imageFirst))" width="300px"/>
But all I get is this icon:
I can't for the love of me figure out why it can't be shown. The images are stored as what I can only assume is a blob in the database, but right now I wish they were just image files on the disc, as that seems to make it a lot easier to attach them to the view.
Assuming the imageFirst property is a valid image byte array, you may need to include html raw mode on the output:
<img src="data:image/jpg;base64,#Html.Raw(Convert.ToBase64String(item.imageFirst))" width="300px"/>
Also, use item instead of #item since you are already inside of #(), or in the example #Html.Raw.
Which browser you are using. IE has a size limit on the data URI, I think it is 32 KB. What is the size of your image string after converting to base64.
I have been able to upload an image to sql server, in binary format. This is the code that I am using to upload it..
protected void Button2_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string filename = FileUpload1.FileName;
Stream imgStream = FileUpload1.PostedFile.InputStream;
int imgLen = FileUpload1.PostedFile.ContentLength;
byte[] imgBinaryData = new byte[imgLen];
string strCm = "s_PictInsert";
SqlCommand cm = new SqlCommand(strCm, Cn);
cm.CommandType = CommandType.StoredProcedure;
cm.Parameters.Add(new SqlParameter("#TheImage", SqlDbType.Image)).Value = imgBinaryData;
Cn.Open();
cm.ExecuteNonQuery();
Cn.Close();
}
}
When I look at the database, all I see in the database, of the pic I uploaded, is 0x00000000000000 etc...I don't know why it looks like that...
Then I am using this code to retrieve the image..
protected void Button3_Click(object sender, EventArgs e)
{
string strCm = "select TheImage from [Pictures] where PictureID = 2";
SqlCommand cm = new SqlCommand(strCm, Cn);
cm.CommandType = CommandType.Text;
Cn.Open();
SqlDataReader dr = cm.ExecuteReader();
if (dr.Read())
{
Response.ContentType = "image/jpg";
Response.BinaryWrite((byte[])dr["TheImage"]);
}
Cn.Close();
}
when I click the button it doesn't show me the image it just writes the markup out to the page.
What I want to do is retrieve the image and put it to an asp image, the thing is the images that I upload can be .png format.
I only used response.binarywrite is because that is what I was shown to do. But it doesn't work the way I was told it would.
Thanks
The problem is with your upload function, you are not setting imgBinaryData with the data from the file stream, you are only settings the size to match, so it will default to all zeros.
Instead of this part:
byte[] imgBinaryData = new byte[imgLen];
Replace it with this:
byte[] imgBinaryData = null;
using (var reader = new BinaryReader(FileUpload1.PostedFile.InputStream))
{
imgBinaryData = reader.ReadBytes(FileUpload1.PostedFile.ContentLength);
}
Then check to see what your database data looks like.
On a side note, I would recommend always storing file name and MIME type when storing files in a database, you never know when you will need them!
try this:
var length = FileUpload1.PostedFile.ContentLength;
Byte[] imgBinaryData = new Byte[length];
var stream = FileUpload1.FileContent;
stream.Read(imgBinaryData, 0, length);
then insert the binary object. Your code does not read the image into the stream for insertion. The above code should read the image into the byte array, then your db code should insert actual data instead of the placeholder.
You are storing image in binary format to the database, you will retrieve the same. You need to use MemoryStream to get the image from the byte array that you retrieved.
See this :
Retrieve image from database and display on ASP.NET without httphandler
I am using the following function to store image in db
void SaveImage(byte[] image)
{
MySqlConnection con = new MySqlConnection(db);//new connection is made
con.Open();
string cmdText = "INSERT INTO Picture(RoomNo ,pic )VALUES ('" + RoomNo.Text + "',?Image)";
MySqlCommand cmd = new MySqlCommand(cmdText, con);
cmd.Parameters.Add("?Image", image);
cmd.ExecuteNonQuery();
}
In main I am calling the function like this
using (var ms = new MemoryStream())
{
picbox.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
SaveImage(ms.ToArray());
}
I do not know how to display it in a picture box .. can any one help me???
Are you using Windows Forms? And you must Convert Byte array to Image for displaying it in Picture Box.
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
And how did you convert Image to byte array. I hope that problem not there. You can use:
private byte[] ImageToByteArray(string ImageFile)
{
FileStream stream = new FileStream(
ImageFile, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(stream);
// Convert image to byte array.
byte[] photo = reader.ReadBytes((int)stream.Length);
return photo;
}
set your image picture box using Image method (FromStream)
yourPictureBox.Image = Image.FromStream(ms);
I am storing images in a database and would like to convert them from byte array to image. I have no problem converting an object to byte array but I get an error of "Parameter is not valid" when trying to convert from byte array to image. The object I am passing to my method is from a dataset row.
Stored procedure
USE [----------------]
GO
/****** Object: StoredProcedure [dbo].[usp_imageloader_add_test] Script Date: 01/16/2012 09:19:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[usp_imageloader_add_test]
#p_Image Image
as
INSERT into Test_Images VALUES(#p_Image)
Upload File control /convert Image file to byte array and save data to database
protected void btnUpload_Click(object sender, EventArgs e)
{
if (ctrlUpload.PostedFile != null)
{
if (ctrlUpload.PostedFile.ContentLength > 0)
{
// Get Posted File
HttpPostedFile objHttpPostedFile = ctrlUpload.PostedFile;
// Find its length and convert it to byte array
int ContentLength = objHttpPostedFile.ContentLength;
// Create Byte Array
byte[] bytImg = new byte[ContentLength];
// Read Uploaded file in Byte Array
objHttpPostedFile.InputStream.Read(bytImg, 0, ContentLength);
using (SqlConnection dbConnection = new SqlConnection(app_settings.sql_conn_string_db))
{
try
{
string sql = "usp_imageloader_add_test";
SqlCommand cmd = new SqlCommand(sql, dbConnection);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#p_Image", bytImg).SqlDbType = SqlDbType.Image;
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
catch (Exception ex)
{
ex.Message.ToString();
}
}
}
}
}
Convert object to byte array and to image
private System.Drawing.Image ObjToImg(object obj)
{
byte[] byteArray;
if (obj == null)
return null;
else
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
byteArray = ms.ToArray(); // Byte Array
ms.Close();
ms = new MemoryStream(byteArray, 0, byteArray.Length);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
return returnImage;
}
Any ideas would be helpful.
Image.FromStream is probably throwing an ArgumentException because the image format is invalid. Expecting a random serialized object to be formatted as a valid image is not reasonable.
Is the data you're using raw RGB data? If so, there's a user comment in the docs for FromStream() that mentions that the method will throw if the stream contains raw RGB data: http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx (see the bottom of the page); it recommends using a Bitmap instead (http://msdn.microsoft.com/en-us/library/zy1a2d14.aspx).
Try the following, your stream may not be initialized to the beginning:
ms = new MemoryStream(byteArray, 0, byteArray.Length);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
What type of image is it? Are you sure the image that is stored is valid?
Also just a comment on usage (won't affect your issue), it is good practice to use a using statement when working with streams. Eg:
using (MemoryStream ms = new MemoryStream())
{
// your code here
}
The solution by Kelsey should work. This is because, when you read data from byteArray to memory stream, the pointer is placed at the end of the stream, and now when you try to read data from this memory stream, it tries to read head of this pointer, and as there is no data after this, you get an error. Now if you do ms.Seek(0, SeekOrigin.Begin);, the reader pointer is placed at the beginning of the memory stream. And dispose the memory stream when you are done using it ms.Dispose(). Hope this helps.
You don't need the binary formatter, that's what's messing with your data, it's for serializing objects really.
The key thing to note is that the object is a byte array already so you can just cast it and use that.
Try this:-
private System.Drawing.Image ObjToImg(object obj)
{
if (obj == null)
return null;
else
{
byte[] byteArray = (byte[])obj;
System.Drawing.Image returnImage;
using (var ms = new MemoryStream(byteArray, 0, byteArray.Length))
{
returnImage = System.Drawing.Image.FromStream(ms);
}
return returnImage;
}
}