I'm comparing two images; the source is in my solution (and saving it to memory stream) and other I am downloading using 'WebClient' converting it to bytes and then saving it in a stream, then comparing the streams.
They are exactly the same image. However my code produces different hash strings, so the 'If Equals' produces a false.
I'm thinking the downloading and saving of the image is altering the string.
The code:
public void CompareImages(string icon)
{
WebClient wc = new WebClient();
MemoryStream ms = new MemoryStream();
Image expectedImage = Image.FromFile(AppConfig.ToolsFilesFolderName + string.Format("\\" + icon +".png"));
expectedImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
String firstBitmap = Convert.ToBase64String(ms.ToArray());
ms.Position = 0;
MemoryStream ms2 = null;
byte[] bytes;
var baseEventType = _driver.FindElement(By.XPath("//div[#id='EventsView2_tv']/div/div")); ///div/div/div[19] //what i need to do is expand all of them and then
int count = 0;
var eventTypeExists = baseEventType.FindElements(By.TagName("tr"));
for (int i = 0; i < eventTypeExists.Count; i++)
{
if (i>30)
return;
if (eventTypeExists[i].Text.Trim().ToLower().Equals(icon.ToLower()))
{
var imgPath = eventTypeExists[i].FindElement(By.XPath("td[3]/img"));
var imageUrl = imgPath.GetAttribute("src");
bytes = wc.DownloadData(imageUrl);
ms2 = new MemoryStream(bytes);
Image actualImage = Image.FromStream(ms2);
actualImage.Save(ms2, System.Drawing.Imaging.ImageFormat.Png);
String secondBitmap = Convert.ToBase64String(ms2.ToArray());
if (firstBitmap.Equals(secondBitmap))
{
Reporter.ReportNote(string.Format("'{0}' icon in '{1}' is correct",
icon, ScenarioContext.Current["contractName"] + "/" + eventTypeExists[i].FindElement(By.XPath("../../../../table[" + (i - 2) + "]")).Text),
Status.Pass);
}
else
{
Reporter.ReportNote(string.Format("Icons are not correct, offending image is located within '{0}'",
ScenarioContext.Current["contractName"] + "/" + eventTypeExists[i].FindElement(By.XPath("../../../../table[" + (i - 2) +"]")).Text),
Status.Done);
}
ms2.Dispose();
}
count++;
}
ms.Dispose();
wc.Dispose();
}
Related
I am loading an image and i get an increase of memory around 10x the size of the file.
this is the output for the code below
Loading file img_6.jpg with originally 513kb
Memory for image img_6.jpg is 63704kb (124.12x)
Thanks!
this is the code i use to load
string filename = "img_6.jpg";
Directory.SetCurrentDirectory(#"C:\Users\Admin\Desktop\isolated images");
Helpers.membefore(filename);
BitmapImage bitmap = new BitmapImage();
//using (Stream stream = new FileStream(filepath, FileMode.Open))
{
bitmap.BeginInit();
//bitmap.StreamSource = stream;
bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.UriSource = new Uri(filename, UriKind.Relative);
bitmap.EndInit();
}
ImageBrush ib = new ImageBrush() { ImageSource = bitmap };
Helpers.memafter(ib);
these are the memory log helpers
public static void memafter(object result)
{
//debugging
if (result.GetType() == typeof(ImageBrush) && (result as ImageBrush).ImageSource != null)
{
var after = Process.GetCurrentProcess().VirtualMemorySize64;
string factor = ((double)(after - before) / (double)len).ToString("N") ;
string source = (result as ImageBrush).ImageSource.ToString();
Console.WriteLine(String.Format("Memory for image {0} is {1}kb ({2}x)",
source,
(after - before) / 1024,
factor.ToString()));
string s = result.ToString();
}
}
public static void membefore(string xaml)
{
FileInfo fi = new FileInfo(xaml);
len = fi.Length;
Console.WriteLine(string.Format("Loading file {0} with originally {1}kb", xaml, fi.Length / 1024));
if (xaml.Contains("ico") || xaml.Contains("jpg") || xaml.Contains("bmp") || xaml.Contains("png"))
{
before = Process.GetCurrentProcess().VirtualMemorySize64;
}
}
private static long len = 0;
static long before = 0;
Ok right,
the reason there are different file formats was behind it.
Irfanview helped a lot with pressing I opening image information shows file and loaded memory size.
I'm using Zxing library to create a barcode and memory stream to save it to the server folder.
Everything works fine on local as well as a testing server, but when I publish code on client-server it won't create a barcode image nor get location of image on that server location.
Here is the code I created for this process-
var writer = new BarcodeWriter();
writer.Format = BarcodeFormat.CODE_128;// QR_CODE;
var result = writer.Write(printArray[0]);
string path = Server.MapPath("/images/code/" + ComplaintId + ".jpg");
var barcodeBitmap = new Bitmap(result);
using (MemoryStream memory = new MemoryStream())
{
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
{
barcodeBitmap.Save(memory, ImageFormat.Jpeg);
byte[] bytes = memory.ToArray();
fs.Write(bytes, 0, bytes.Length);
}
}
This code is used to save bar code on the server location.
string ImagePath = ComplaintId + ".jpg";
imgQRcode.Src = "~/images/code/" + ImagePath;
and used this line to bind it to img tag.
it shows error like
Could not find a part of the path g:\xyz\images\code\103.jpg
this only happen on client-server not elsewhere.
---------Edit 1--------
As I was still facing issues while creating image on a host server, I made a few changes in code now. Instead of saving barcode image I'm converting it to Base64 string and using it.
Here is code changes
var barWriter = new BarcodeWriter();
barWriter.Format = BarcodeFormat.CODE_128;// QR_CODE;
var barResult = barWriter.Write("printbar");
var barcodeBitmap = new Bitmap(barResult);
string bs64 = ToBase64String(barcodeBitmap, ImageFormat.Jpeg);
and Tobase64String function
public static string ToBase64String(Bitmap bmp, ImageFormat imageFormat)
{
string base64String = string.Empty;
MemoryStream memoryStream = new MemoryStream();
bmp.Save(memoryStream, imageFormat);
memoryStream.Position = 0;
byte[] byteBuffer = memoryStream.ToArray();
memoryStream.Close();
base64String = Convert.ToBase64String(byteBuffer);
byteBuffer = null;
return base64String;
}
and function to bind base64 to image
public static string GetImageSrc(string base64Src)
{
return "data:image/png;base64," + base64Src;
}
to feed it to iTextcharp use
byte[] imageBytes = Convert.FromBase64String(bs64);
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imageBytes);
I'm saving images into the table using this code:
if (FileUploadControl.PostedFile.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
{
byte[] imagedata = MSImage.ConvertToByte(FileUploadControl);
if (imagedata != null)
{
string param = "#Image";
SqlParameter sp = spc.Add(new SqlParameter(param, SqlDbType.VarBinary, -1));
sp.Value = imagedata;
sql += ", " + Q.C(Database.MSImage) + "=" + param + ", " + Q.C(Database.MSImageType) + "=N'" + FileUploadControl.PostedFile.ContentType + "'";
}
}
And attempting to load it into background-image style with this code:
string imagedata = MSImage.ConvertToImage((byte[])ms[Database.MSImage]);
if (imagedata != null && ms[Database.MSImageType] != DBNull.Value && ((string)ms[Database.MSImageType]).StartsWith("image/", StringComparison.OrdinalIgnoreCase))
{
takzir2.InnerHtml = "<div class='msbgimage' style=\"background-image:url(data:" + (string)ms[Database.MSImageType] + ";base64, " + imagedata + ")\"></div>";
}
The problem is that it won't load the image, and when I try inspecting the element, it gets really stuck because the converted byte array returned a very long string (that sums up in about 650k characters).
This is my MSImage class:
public class MSImage
{
public static byte[] ConvertToByte(FileUpload hpf)
{
try
{
if (hpf.HasFile)
{
Stream fs = hpf.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
return bytes;
}
}
catch { }
return null;
}
public static string ConvertToImage(byte[] imagedata)
{
try
{
if (imagedata != null && imagedata.Length > 0)
return Convert.ToBase64String(imagedata);
}
catch { }
return null;
}
}
Am I saving the image in a wrong way or is it the loading that causes the issue?
EDIT:
I just found out that this code is the problem:
takzir2.InnerHtml = "<div class='msbgimage' style=\"background-image:url(data:" + (string)ms[Database.MSImageType] + ";base64, " + imagedata + ")\"></div>";
I tried using a div that has runat="server" and it worked with div.Style["background-image"], but how can I make it work with InnerHtml?
I'm using following Code to convert my Images, maybe you find a difference...
static string Image2Base64(Image image)
{
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imageBytes = ms.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
static Bitmap Base642Image(string base64image)
{
try
{
byte[] imageBytes = Convert.FromBase64String(base64image);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
Bitmap image = (Bitmap)Image.FromStream(ms, true);
return image;
}
catch { return null; }
}
I hope this might help you...
I just found the solution (It's a silly one though):
This line of code was causing the problem:
takzir2.InnerHtml = "<div class='msbgimage' style=\"background-image:url(data:" + (string)ms[Database.MSImageType] + ";base64, " + imagedata + ")\"></div>";
I changed the end of it from:
";base64, " + imagedata + ")\"></div>";
To:
";base64," + imagedata + ")\"></div>";
The space between ";base64," to imagedata was causing it because InnerHtml didn't replace the space character with %20.
I'm trying to convert a stream to image using C#, but the image is appearing corrupt.
Here is how i'm getting the BaseString representation
byte[] imageArray = System.IO.File.ReadAllBytes(#"C:\Users\jay.raj\Desktop\images\images\tiger.jpg");
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
Now I'm passing this to a function which converts it into Stream and tries to convert it into image file.
byte[] byteArray = Encoding.ASCII.GetBytes(mySettingInfo.FileToUpload);
MemoryStream stream = new MemoryStream(byteArray);
UtilityHelper.UploadImageFormDevice(stream, ref ss);
Here is the UploadImageFormDevice function:
public static ResponseBase UploadImageFormDevice(Stream image, ref string imageName)
{
ResponseBase rep = new ResponseBase();
try
{
string filname = imageName;
string filePath = #"C:\Users\jay.raj\Desktop\Upload\";
if (filname == string.Empty)
filname = Guid.NewGuid().ToString() + ".jpg";
filePath = filePath + "\\" + filname;
FileStream fileStream = null;
using (fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 1024;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = image.Read(buffer, 0, bufferLen)) > 0)
{
fileStream.Write(buffer, 0, count);
}
fileStream.Close();
image.Close();
}
imageName = filname;
}
catch (Exception ex)
{
rep.Code = 1000;
rep.Message = "Server Error";
}
return rep;
}
As #naivists wrote try replace this line:
byte[] byteArray = Encoding.ASCII.GetBytes(mySettingInfo.FileToUpload);
To this line:
byte[] byteArray = Convert.FromBase64String(mySettingInfo.FileToUpload);
It looks like you want to transfer a file from #"C:\Users\jay.raj\Desktop\images\images\tiger.jpg" to #"C:\Users\jay.raj\Desktop\Upload\" + "\\" + Guid.NewGuid().ToString() + ".jpg".
In your case you read the file as a byte array, convert it into a base 64 coded string and then again into a byte array. This is unnecessary and error prone. In your case you missed the decoding.
If you ignore for a moment that it is an image and see it just as a bunch of bytes things might get easier.
string srcPath = #"C:\Users\jay.raj\Desktop\images\images\tiger.jpg";
string dstPath = #"C:\Users\jay.raj\Desktop\Upload\" + "\\" + Guid.NewGuid().ToString() + ".jpg";
byte[] imageArray = System.IO.File.ReadAllBytes(srcPath);
System.IO.File.WriteAllBytes(dstPath, imageArray);
Following is the code to retrieve image from database and then saving it to a folder.
public string BinarytoNewsImage(int ID)
{
byte[] btimage = null;
string image = "";
string filename = null;
int mediaid;
DataSet dsNews = new DataSet();
adp = new SqlDataAdapter("Select Top 1 * from tblNew Where intNewId=" + ID, offcon);
adp.Fill(dsNews, "tblNews1");
if (dsNews.Tables["tblNews1"].Rows.Count > 0)
{
if (dsNews.Tables["tblNews1"].Rows[0]["strImage"] != DBNull.Value)
{
btimage = (byte[])dsNews.Tables["tblNews1"].Rows[0]["strImage"];
mediaid = Convert.ToInt32(dsNews.Tables["tblNews1"].Rows[0]["intMediaId"].ToString());
filename = dsNews.Tables["tblNews1"].Rows[0]["strfilename"].ToString();
image = BinarytoImage(btimage, mediaid);
}
else
{
filename = dsNews.Tables["tblNews1"].Rows[0]["strfilename"].ToString();
image = "http://www.patrika.com/media/" + filename;
}
}
return image;
}
public string BinarytoImage(byte[] stream, int ID)
{
string ImagePath = "";
string Image = ID + ".jpg";
var URL = System.Configuration.ConfigurationManager.AppSettings["ImagePath"].ToString();
string FolderName = new Uri(URL).LocalPath;
var help = HttpContext.Current.Server.MapPath(FolderName);
if (Directory.Exists(HttpContext.Current.Server.MapPath(FolderName)))
{
string[] files = Directory.GetFiles(HttpContext.Current.Server.MapPath(FolderName), ID + ".jpg");
if (files.Length > 0)
{
ImagePath = URL + ID + ".jpg";
}
else
{
using (MemoryStream MS = new MemoryStream(stream, 0, stream.Length))
{
MS.Write(stream, 0, stream.Length);
System.Drawing.Image img = System.Drawing.Image.FromStream(MS);
img.Save(help + ID + ".jpg", System.Drawing.Imaging.ImageFormat.Gif);
img.Dispose();
img = null;
ImagePath = URL + ID + ".jpg";
}
}
}
return ImagePath;
}
Everything is working fine the images are saving to a folder but my problem is images are getting blur after retrieval.
I just don't know the reason as when I am using another code for retrieval than images are coming fine but are not saved to folder:
DataSet dsNews = new DataSet();
adp = new SqlDataAdapter("Select Top 1 * from tblNew Where intNewId=901371", con);
adp.Fill(dsNews, "tblNews1");
if (dsNews.Tables["tblNews1"].Rows[0]["strImage"] != DBNull.Value)
{
byte[] btimage = (byte[])dsNews.Tables["tblNews1"].Rows[0]["strImage"];
Response.ContentType = "image/jpeg";
Response.BinaryWrite(btimage);
}
I need those images to be saved to folder so that I don't have to call database after once image comes.
Wouldn't it help to change this line
img.Save(help + ID + ".jpg", System.Drawing.Imaging.ImageFormat.Gif);
to store it as JPEG rather? as that's the source format
EDIT:
Your are not moving the stream pointer back to the start.
Try change these lines:
using (MemoryStream MS = new MemoryStream(stream, 0, stream.Length))
{
MS.Write(stream, 0, stream.Length);
System.Drawing.Image img = System.Drawing.Image.FromStream(MS);
...
To
using (MemoryStream MS = new MemoryStream(stream, 0, stream.Length))
{
MS.Write(stream, 0, stream.Length);
MS.Seek(0, SeekOrigin.Begin);
System.Drawing.Image img = System.Drawing.Image.FromStream(MS);
...
I write the common method, all is ok.
Maybe your byte[]stream is not right,pls check.
byte[] stream = File.ReadAllBytes(#"D:\YWG\123.jpg");
using (MemoryStream MS = new MemoryStream(stream, 0, stream.Length))
{
MS.Write(stream, 0, stream.Length);
using (Image img = Image.FromStream(MS))
{
img.Save(#"D:\dd.jpg", System.Drawing.Imaging.ImageFormat.Gif);
}
}
I see the dest file "dd.jpg" is ok.