storing image inside db using winforms - c#

I want to save Image inside SqlServer using c# winforms and dapper micro orm.
Photo field inside db is of type VARBINARY(MAX)
Inside Book entity I have Photo property of type byte[].
public Book
{
...
public byte[] Photo { get; set; }
}
Inside winforms Window I have
OpenFileDialog open = new OpenFileDialog() { Filter = "Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.png;*.jpg" };
if (open.ShowDialog() == DialogResult.OK)
{
txtPhoto.Text = open.FileName;
}
string image = txtPhoto.Text;
Bitmap bmp = new Bitmap(image);
FileStream fs = new FileStream(image, FileMode.Open, FileAccess.Read);
byte[] bimage = new byte[fs.Length];
fs.Read(bimage, 0, Convert.ToInt32(fs.Length));
fs.Close();
byte[] Photo = bimage;
// inside my repository I have error on saving object at line Photo = #Photo
var sql = "UPDATE Book " +
"SET Title = #Title, " +
" Language = #Language, " +
....
" Photo = #Photo" +
"WHERE Id = #Id";
this.db.Execute(sql, book); // error occures
return book;
Error is
A first chance exception of type 'System.Data.SqlClient.SqlException'
occurred in System.Data.dll
Additional information: Incorrect syntax near 'Photo'.
Am I missing something?
Thanks

You are missing white space before WHERE keyword:
" Photo = #Photo" + // no space at the end here
"WHERE Id = #Id"; // and no space before WHERE here
Also I suggest you to use multiline string (i.e. verbatim string literal) for sql query text (that makes query more readable):
var sql = #"UPDATE Book
SET Title = #Title,
Language = #Language,
Photo = #Photo
WHERE Id = #Id";
And one more thing - it's better to wrap Stream usage into using block (in order to release file handle in case of exception):
byte[] photo;
using(var stream = File.OpenRead(txtPhoto.Text)
{
photo = new byte[stream.Length];
stream.Read(photo, 0, photo.Length);
}
// db query with dapper is OK

Related

Display.ashx not displaying image name with character &

I have a situation where Display.ashx displays successfully images from Sql server with only letters(e.g Coffee or Green tea) in it but when a image name is saved as (Coffee & Froth) it does not display.please see code below,i placed a break point on Img in Display class and when the imagename is Coffee the full string is passed but when the image name is Coffee & Froth it cuts the froth and only takes Coffee,meaning it takes only the string before the character &.can someone please please show me a workaround so it takes the whole string with the character.Thanks
public class Display : IHttpHandler
{
public Stream Displays(string Img)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DB"].ConnectionString.ToString()))
{
string sql = string.Format("select top 1 img from Images where Name = '{0}'", Img);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
cmd.Connection.Open();
object imagevalue = cmd.ExecuteScalar();
if (imagevalue != null && imagevalue != DBNull.Value)
{
return new MemoryStream((byte[])imagevalue);
}
using (FileStream fs = File.OpenRead(HttpContext.Current.Server.MapPath(#"~/Content/noimage.png")))
{
MemoryStream memStream = new MemoryStream();
memStream.SetLength(fs.Length);
fs.Read(memStream.GetBuffer(), 0, (int)fs.Length);
return memStream;
}
}
}
#endregion
This is how i call the Image
protected void Refresh_SelectedIndexChanged(object sender, EventArgs e)
{
// string id = CoffeeMenu.SelectedValue;
Image1.ImageUrl = "~/Display.ashx?id=" + "Coffee & Froth";
divSuccess.Visible = false;
divError.Visible = false;
}
HTML
<asp:DropDownList ID="CoffeeMenu" runat="server" CssClass="selectpicker" OnSelectedIndexChanged="Refresh_SelectedIndexChanged"/>
Encode the data part:
Image1.ImageUrl = "~/Display.ashx?id=" + Server.UrlEncode("Coffee & Froth");
The problem you have is that an & is used to split values in a url so extra parameters for your display would look like:
?name=blah&resize=1920x1080&convert=png&rotate=90
As such your "Coffee & Froth" is probably being requested by the browser as Coffee+&+Froth and is being received and interpreted by your ashx as having these parameters:
{
"id": "Coffee ",
" Froth": null
}
Or, strip anything that's not a number or letter out of the filename; looks like you're in control of the naming of these things as they're stored on disk so make life simple
(moving comment to answer)
Try Coffee & Froth or Coffee%20%26%20Froth
& is used in HTML to represent &
%20 is hexadecimal for space and %26 is hexadecimal for &. Hexadecimal is often used to encode special characters in URLs.
Full ASCII table:
https://en.wikipedia.org/wiki/ASCII#Printable_characters

A generic error occured in GDI+ while saving image

I have to save an image in post request in byte64String format
when i save that image i get A generic error occurred in GDI+
here is my code
byte[] ix = Convert.FromBase64String(obj.Image);
var ID = obj.Id;
using (var mStream = new MemoryStream(ix))
{
var img = Image.FromStream(mStream);
var image = obj.ImageName + ".jpg";
string path = HostingEnvironment.MapPath("/Images/" + ImageType + "/" + ID + "/" + image);
System.IO.Directory.CreateDirectory(path);
try
{
img.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception e)
{
var d = e;
}
}
also
this is not a permission issue as i am able to create text files in the same directory
Quite simply you are confusing paths and filenames.
The problem if could hazzard a guess, you probably have a folder that is your filename, and you are trying to save a file with that same name, which windows forbids
Your code tweaked
var image = $"{obj.ImageName }.jpg";
// get the path, and only the path
string path = HostingEnvironment.MapPath($"/Images/{ImageType}/{ID}/");
// Create directory if needed (from that path)
Directory.CreateDirectory(path,image);
...
// now create the correct full path
var fullPath = Path.Combine(path,fileName);
// save
img.Save(fullPath, ImageFormat.Jpeg);

Read Image file metadata

I want to upload an image file and then extract its basic information (author, dimensions, date created, modified, etc) and display it to the user. How can I do it.
A solution or reference to this problem in asp.net c# code would be helpful. But javascript or php would be ok as well.
Check this Link. You will get more Clearance about GetDetailsOf() and its File Properties based on the Win-OS version wise.
If you want to use C# code use below code to get Metadata's:
List<string> arrHeaders = new List<string>();
Shell shell = new ShellClass();
Folder rFolder = shell.NameSpace(_rootPath);
FolderItem rFiles = rFolder.ParseName(filename);
for (int i = 0; i < short.MaxValue; i++)
{
string value = rFolder.GetDetailsOf(rFiles, i).Trim();
arrHeaders.Add(value);
}
C# solution could be found here:
Link1
Link2
Bitmap image = new Bitmap(fileName);
PropertyItem[] propItems = image.PropertyItems;
foreach (PropertyItem item in propItems)
{
Console.WriteLine("iD: 0x" + item.Id.ToString("x"));
}
MSDN Reference
C# Tutorial Reference
try this...
private string doUpload()
{
// Initialize variables
string sSavePath;
sSavePath = "images/";
// Check file size (mustn’t be 0)
HttpPostedFile myFile = FileUpload1.PostedFile;
int nFileLen = myFile.ContentLength;
if (nFileLen == 0)
{
//**************
//lblOutput.Text = "No file was uploaded.";
return null;
}
// Check file extension (must be JPG)
if (System.IO.Path.GetExtension(myFile.FileName).ToLower() != ".jpg")
{
//**************
//lblOutput.Text = "The file must have an extension of JPG";
return null;
}
// Read file into a data stream
byte[] myData = new Byte[nFileLen];
myFile.InputStream.Read(myData, 0, nFileLen);
// Make sure a duplicate file doesn’t exist. If it does, keep on appending an
// incremental numeric until it is unique
string sFilename = System.IO.Path.GetFileName(myFile.FileName);
int file_append = 0;
while (System.IO.File.Exists(Server.MapPath(sSavePath + sFilename)))
{
file_append++;
sFilename = System.IO.Path.GetFileNameWithoutExtension(myFile.FileName)
+ file_append.ToString() + ".jpg";
}
// Save the stream to disk
System.IO.FileStream newFile
= new System.IO.FileStream(Server.MapPath(sSavePath + sFilename),
System.IO.FileMode.Create);
newFile.Write(myData, 0, myData.Length);
newFile.Close();
return sFilename;
}

Error while saving binary image from database to folder

I need to retrieve an image from a database and save it to disk. In the database, the image is stored in binary format but datatype of the column is varchar(5000).
This is the code that I am using for retrieving the image and saving it to disk
public void CreateImageDataUsingDataReader_ForNetezzaDB()
{
string strDbConn = string.Empty;
string strImageFileName = string.Empty;
string strImageData = string.Empty;
string strImgSavePath = string.Empty;
string strQuery = string.Empty;
Byte[] byteImageData;
MemoryStream stmImageData = new MemoryStream();
Image saveImage;
try
{
//---open the database connection
strDbConn = ConfigurationSettings.AppSettings["NetezzaDBConnection"].ToString().Trim();
OleDbConnection dbcon = new OleDbConnection(strDbConn);
dbcon.Open();
strQuery = "select name,signature_vod__c from sfb_call2_vod where signature_vod__c is not null limit 10";
OleDbCommand cmdSelect = new OleDbCommand(strQuery, dbcon);
OleDbDataReader imageReader = cmdSelect.ExecuteReader();
if (imageReader.HasRows)
{
while (imageReader.Read())
{
strImageFileName = imageReader["name"].ToString().Trim();
strImageData = imageReader["signature_vod__c"].ToString().Trim();
stmImageData.Seek(0, SeekOrigin.Begin);
//converting string to byte array
byteImageData = Convert.FromBase64String(strImageData);
//---create Memory stremm from the Image Byte data
stmImageData.Write(byteImageData, 0, byteImageData.Length);
//--saving the image
//saveImage = Image.FromStream(stmImageData);
using (saveImage = Image.FromStream(stmImageData))
{
strImgSavePath = ConfigurationSettings.AppSettings["ImageSavePath"].ToString().Trim();
saveImage.Save(strImgSavePath + strImageFileName + ".png", System.Drawing.Imaging.ImageFormat.Png); ///---error comes in this line
}
}
}
imageReader.Close();
dbcon.Close();
stmImageData.Close();
stmImageData = null;
}
catch (Exception ex)
{
throw new Exception("Error Occured in method CreateImageDataUsingDataReader " + ex.Message);
}
}
but I keep getting an error:
A generic error occurred in GDI+.
Same code if I execute for SQL Server database it works fine but issue comes only with the Netezza database
Please help me resolve this issue
You mention that you store the binary image in a varchar column. This and the fact that it works on an other db technology makes it obious that you read different data back in the Netazza case.
I would suggest to setup a testproject where you persist the same image to the 2 different databases (netazza and mssql), read it back from both a do a bitwise comparison of the result either between the db results or between original and read from db.
I would be surprised if you get the same result and if I am right, you should probalaby consider to use a binary data type to persist the image data in your db backend.

Error while saving an image

I want to save an image after some changes in image.
but I am getting an error while calling .Save() function.
var tempapth = Server.MapPath("..//Images//Temp//" + btnfile.FileName);
btnfile.SaveAs(tempapth);
using (var fileStream = File.OpenRead(tempapth))
{
var ms = new MemoryStream();
fileStream.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Image img1 = System.Drawing.Image.FromStream(ms);
fileStream.Close();
var bmp1 = img1.GetThumbnailImage(100, 150, null, IntPtr.Zero);
bmp1.Save(path);
}
bmp1.save(path);
give an error
A generic error occurred in GDI+
EDIT
The OP changed the question after I wrote this reply. Previously, there was also a path variable declared, which contained a path name (but no file name).
In the first version of your code, you had a path name without a file name (Server.MapPath("..//Images//Category//" + catid + "//");). To save, you need to add a file name, too, like:
string path = Server.MapPath("..//Images//Category//" + catid + "//Image.bmp");
The path variable contains the name of a folder, not a file.
Use something like:
bmp1.Save(Path.Combine(path, btnfile.FileName));
Side note, the character / doesn't have a special meaning in a string, it should not be escaped. Use:
var path = Server.MapPath("../Images/Category/" + catid + "/");
how about:
var srcPath = Server.MapPath("..//Images//Temp//" + btnfile.FileName);
if (!File.Exists(srcPath)
{
throw new Exception(string.Format("Could not find source file at {0}", srcPath));
}
var srcImage = Image.FromFile(srcPath);
var thumb = srcImage.GetThumbnailImage(100, 150, null, IntPtr.Zero);
var destPath = Server.MapPath("..//Images//Category//" + catid + "//");
if (!Directory.Exists(destPath))
{
Directory.CreateDirectory(destPath);
}
thumb.Save(Path.Combine(destPath, btnfile.FileName));

Categories

Resources