I am trying to upload an image in sql server using K2 ImageAttachment when I am doing InputMapping the image gets stored as an xml having file path. I want to store it as base64 string of image not xml path but the actual image base64 string. Any clue?
<collection><object><fields><field name='FileName'><value>Capture.PNG</value></field><field name='FilePath'><value>AB177CDDBA29104CD0E1AE3F14DCDD4B\Capture.PNG</value></field><field name='FileRequestData'><value></value></field><field name='FileDataURL'><value></value></field></fields></object></collection>
I did this via C#;
// BMP, GIF, JPEG, PNG, TIFF
using (System.Drawing.Image img = System.Drawing.Image.FromFile(imgPath))
{
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, img.RawFormat);
imgNode.Attributes["src"].Value = "data:image/" + imgName.Substring(imgName.LastIndexOf('.') + 1) + #";base64," + Convert.ToBase64String(ms.ToArray());
}
}
Related
I'm trying to generate a Word document through my application coded in WPF. In that document, I also need to layout few images along with caption as shown in the image below.
All the images are stored in database as base64 string. I'm able to load the images as "BitmapImage" object in the document however not sure how to layout the images as shown in image. Code snippet to load the images in document is as below :
var bookmarks = wordDoc.Bookmarks;
var range = bookmarks["ExternalImage"].Range;
foreach (var image in ExternalImages) // here image is "BitmapImage" object
{
float scaleHeight = (float)250 / (float)image.Image.PixelHeight;
float scaleWidth = (float)250 / (float)image.Image.PixelWidth;
var min = Math.Min(scaleHeight, scaleWidth);
var bitmap = new TransformedBitmap(image, new ScaleTransform(min, min));
System.Windows.Clipboard.SetImage(bitmap);
range.Paste();
}
How can I lay out the images as shown in image above along with caption? Note that I'm not loading images from file but from memory object.
Based on the direction provided by #CindyMeister in comments, following is the working code snippet to layout the images using code :
imageTable = wordDoc.Tables.Add(sel.Range, rows, cols, ref oMissing, ref oMissing);
imageTable.AllowAutoFit = true;
row = 1; col = 1;
foreach (var image in Images)
{
float scaleHeight = (float)475 / (float)image.PixelHeight;
// here 475 is approx image size I want in word document
float scaleWidth = (float)475 / (float)image.PixelWidth;
var min = Math.Min(scaleHeight, scaleWidth);
var bitmap = new TransformedBitmap(image, new ScaleTransform(min, min));
System.Windows.Clipboard.SetImage(bitmap);
//more efficient/faster in C# if you don't "drill down" multiple times to get an object
Word.Cell cel = imageTable.Cell(row, col);
Word.Range rngCell = cel.Range;
Word.Range rngTable = imageTable.Range;
rngCell.Paste();
cel.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
rngCell.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
// set caption below image
rngTable.ParagraphFormat.SpaceAfter = 6;
rngCell.InsertAfter(image.Caption);
rngTable.Font.Name = "Arial Bold";
row++;
}
This code I have posted for reference, only, to let people have some starting point. Any suggestions welcome.
In WPF, I have an image that is dropped onto an InkCanvas and added as a child:
ImageInfo image_Info = e.Data.GetData(typeof(ImageInfo)) as ImageInfo;
if (image_Info != null)
{
Image image = new Image();
image.Width = image_Info.Width * 4;
image.Stretch = Stretch.Uniform;
image.Source = new BitmapImage(image_Info.Uri);
Point position = e.GetPosition(ic);
InkCanvas.SetLeft(image, position.X);
InkCanvas.SetTop(image, position.Y);
ic.Children.Add(image);
}
Then by way of an adorner, the image is moved and resized. It is then persisted to a database as:
public List<string> Children;
var uiList = ic.Children.Cast<UIElement>().ToList();
foreach (var p in uiList)
{
string uis = System.Windows.Markup.XamlWriter.Save(p);
s.Add(uis);
}
Children = s;
Children then being sent on to the database. The resulting record in the database shows as:
"<Image Source="pack://application:,,,/Images/Female - Front.png" Stretch="Uniform" Width="Auto" InkCanvas.Top="296" InkCanvas.Left="695" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" /> "
There is no reference to the new location, size, or rotation of the image--only its initial drop point. Recreating the image with xmlreader restores the image to its initial drop point and size.
foreach (string s in behavior.Children)
{
var stringReader = new StringReader(s);
var xmlReader = System.Xml.XmlReader.Create(stringReader, new System.Xml.XmlReaderSettings());
Image b = (Image)System.Windows.Markup.XamlReader.Load(xmlReader);
ic.Children.Add(b);
}
(The image source is packed as an application resource).
How can I persist the image with its size, location, and rotation and then restore it?
TIA.
Either you can add additional fields to your DB Table for Size / Location / Rotation and store info there.
Or, you can add these fields together as comma(,) separated and store in Tag field of your Image control. <Image Tag="(120,230);(50,50);(-30)" ... />
You can also save entire manipulated image as byte[] in DB.
Please tell if this solves your problem at hand.
OK I managed to upload the word DOCX into my SQL Server database into a varbinary (Max) column.
I can retrieve the DOCX from the database and covert it from varbinary back into an array and offer it as a download with:
Byte[] bytes = (Byte[])dt.Rows[0]["TD_DocFile"];
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = dt.Rows[0]["TD_DocContentType"].ToString();
Response.AddHeader("content-disposition", "attachment;filename="
+ dt.Rows[0]["TD_DocTitle"].ToString());
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
Instead of downloading the document I would prefer to use it in variable so I exchange placeholders in it.
I tried to find a way to convert it to a string or so I can use it for docx eg.
DocX letter = this.document();
Best option I saw so far was the filestream version
public static MemoryStream databaseFileRead(string varID) {
MemoryStream memoryStream = new MemoryStream();
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlQuery = new SqlCommand(#"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = #varID", varConnection)) {
sqlQuery.Parameters.AddWithValue("#varID", varID);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
sqlQueryResult.Read();
var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))];
sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length);
//using (var fs = new MemoryStream(memoryStream, FileMode.Create, FileAccess.Write)) {
memoryStream.Write(blob, 0, blob.Length);
//}
}
}
return memoryStream;
}
But I couldn't convert the binary array bytes nor the memory stream into a variable docx would understand. Maybe I just looked for the wrong conversation. Can someone give me a hint please?
The field is called TD_DocContentType from the database. I can accept that I am weak on the conversion in this instance. I can't see what I am doing wrong. Need a new idea please.
Kind Regards,
Rene
I found the solution for my problem. Took a while and lot of more research to do. I tried to tackle the problem from the wrong angle.
This solution reads the binary field from the database and writes it as a file to an internal web folder called doctemp.
private void download(DataTable dt)
{
var physicalPath = Server.MapPath("~\\doctemp\\{0}");
string outputFileName = string.Format(physicalPath, dt.Rows[0]["TD_DocTitle"]);
filename = outputFileName;
Byte[] bytes = (Byte[])dt.Rows[0]["TD_DocFile"];
File.WriteAllBytes(outputFileName, bytes);
}
I am using VS2010, Silverlight 5.0
I am trying to Import Data from Excel file to Grid, for that I am using an 'OpenFileDialog'. User can Input Excel file using OpenFileDialog like this
OpenFileDialog dlg = new OpenFileDialog();
dlg.Multiselect = false;
dlg.Filter = "Excel Sheet(*.xls)|*.xls|All Files(*.*)|*.*";
bool bResult = (bool)dlg.ShowDialog();
if (!bResult)
return "";
FileInfo info = dlg.File;
StatusText.Text = info.Name;
Stream s = info.OpenRead();
StreamReader reader = new StreamReader(s);
string xml = reader.ReadToEnd();
var doc = XDocument.Parse(xml);
In Case of Microsoft Excel Format 2003 or 2007(.xls file) above code works fine and gives me values from Excel in a string.
But in case of Microsoft Excel Format 2010(.xlsx file) the reader.ReadToEnd() does not return values in proper format so the next line, give me following Error.
var doc = XDocument.Parse(xml);
'Data at the root level is invalid. Line 1, position 1'
How can I solve this error, or what is the best way to import data from excel?
Writing my first silverlight application.
I need to deliver some bitmap that the customer will choose ( used OpenFileDialog ) to the server side ( using web service ).
After the customer choosing the bitmap - i cant access the file and break hit to byte array because i dont see the file full path on the OpenFileDialog object properties.
How can i do it ?
( i have method that get Bitmap and return the bitmap as byte array )
I did that before, here is part of it:
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "Images (*.png; *.jpg)| *.png; *.jpg";
dialog.Multiselect = false;
if (dialog.ShowDialog() == true)
{
using (System.IO.Stream stream = dialog.File.OpenRead())
{
BinaryReader binaryReader = new BinaryReader(stream);
// here are the bytes you want, put them somewhere to send them to the server
byte[] imageBytes = binaryReader.ReadBytes((int)stream.Length);
// here is the filename if you need it
string filename = System.IO.Path.GetFileNameWithoutExtension(dialog.File.Name);
stream.Close();
}
}