I have run into a problem with a C# project I'm working at. I get an object array containing all the selected items from a database row with the function:
public static object[] getResultSet (string statement)
{
object[] resultArray=null;
OleDbConnection con = getConnection();
OleDbCommand command = new OleDbCommand(statement, con);
try
{
con.Open();
OleDbDataReader reader = command.ExecuteReader();
if (reader.Read())
{
resultArray = new object[reader.FieldCount];
reader.GetValues(resultArray);
}
reader.Close();
}
catch (OleDbException ex)
{
MessageBox.Show(ex.ToString(),"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
finally
{
con.Close();
}
return resultArray;
}
and I have this object array in which I have stored all the results:
object[] obj = getResultSet("SELECT * FROM Rooms WHERE ID=1");
I certainly know that the object obj[2] is a BLOB in my database because the debugger shows over 3mil bytes for my object. But when I try to convert the bytes array from the object I get informed that I didn't handle an exception:
"An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Parameter is not valid."
Here's the function I'm using to convert the bytes array to an image:
public static Image imageFromByteArray(byte[] bytearray)
{
Image img;
ImageConverter imgCon = new ImageConverter();
img=(Image)imgCon.ConvertFrom(bytearray);
return img;
}
I tried to call
imageFromByteArray((byte[])obj[2]);
but it didn't work, even with another function that converts an object to a byte array:
public static byte[] objectToByteArray(object obj)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
I have found the solution. Before, I had manually added the image to the database, this is why it behaved so strangely.
In order to be recognized by my program, all the images needed to be programatically added.
Related
I want to read the image stored in Oracle Long datatype. Number of images are stored in a remote Oracle database in a column with datatype long. I just need to retrieve those images and show them on my aspx page. I could retrieve the image from database but when tried to caste it to byte array, it threw error that, string can not be converted to byte[]'. Anybody have any suggestions on how to retrieve these images stored in long column in the database. I have already tried various beginner techniques.
OracleDataReader TableReader = null;
string connectionString = ConfigurationManager.ConnectionStrings["System.Data.OracleClient"].ConnectionString;
using (OracleConnection connection = new OracleConnection(connectionString))
{
connection.Open();
command = new OracleCommand("Select * From IMAGE_TABLE where CUST_ID ='xxxxxxxx' fetch first 1 rows only", connection);
command.InitialLONGFetchSize = -1;
TableReader = command.ExecuteReader();
while (TableReader.Read())
{
try
{
var tt = Convert.ToInt32(TableReader[14]);
byte[] bytes = new byte[tt];
//long bytesRead = TableReader.GetBytes(13, 0, bytes, 0, tt);
//FileStream file = new FileStream("d:\\Img1.jpg", FileMode.Create, FileAccess.Write);
//file.Write(bytes, 0, (int)bytesRead);
//file.Close();
byte[] blob_ =System.Text.UTF32Encoding.ASCII.GetBytes(TableReader[13].ToString());
using (MemoryStream ms = new MemoryStream(blob_))
{
image = Image.FromStream(ms);
}
}
catch (Exception rr)
{
}
}
}
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();
}
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);
I looked around everywhere and we stucked (Since 2 days we are googleing, so pls dont "lmgty"). We want to Convert an image to byte[], in c#.NET, found this method:
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.ToArray();
}
It says:
Thrown: "Cannot access a closed Stream." (System.ObjectDisposedException) Exception Message = "Cannot access a closed Stream.", Exception Type = "System.ObjectDisposedException"
For fixing it i tryed:
ms.Flush();
Our goal is to save the byte[] into the database. We also tried this:
var parameter = new SqlParameter("#Value", SqlDbType.Image)
{
Value = Image
};
cmd.Parameters.Add(parameter);
It says that Bitmap to Byte[] has failed.
The whole insterting command is:
private void CreateEntry()
{
var conn = new SqlConnection(ConfigurationManager.ConnectionStrings[Connectionstring].ConnectionString);
var cmd = new SqlCommand("INSERT INTO _FH_Picture ID, Value, BindItem, Owner, McItemRelated, UploadTime VALUES #ID, #Value, #BindItem, #Owner, #McItemRelated, #UploadTime", conn) { CommandType = CommandType.Text };
cmd.Parameters.AddWithValue("#ID", ID.ToString());
cmd.Parameters.AddWithValue("#Value", imageToByteArray(value));
cmd.Parameters.AddWithValue("#Owner", _owner);
cmd.Parameters.AddWithValue("#BindItem", _bindtitem);
cmd.Parameters.AddWithValue("#McItemRelated", _mcitemrelated);
cmd.Parameters.AddWithValue("#UploadTime", _uploadtime);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
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;
}
}