I'm trying to do a client-server program in which it is possible to share the content of the clipboard.
I got a problem when the clipboard contains an Image. I'm able to encode the BitmapSource to a Byte Array, send it and then decode and inject it into the server clipboard. But when I try to paste the clipboard in a program like Paint or Gimp, I get an error since data is not recognized.
This is the client code:
if (Clipboard.ContainsImage())
{
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(Clipboard.GetImage()));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
return ms.ToArray();
}
}
This is the server code:
JpegBitmapDecoder jpegd = null;
using (MemoryStream ms = new MemoryStream(b)) // b is the byte array received from the client
{
jpegd = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
}
BitmapSource bitmapSource = jpegd.Frames[0];
// Inject data into the clipboard
Clipboard.SetImage(bitmapSource);
Related
I cannot decode images back from their encoded form as a (Jpeg) byte array retrieved from my database to be used as image sources for my WPF application.
The code I am using to encode them as a Jpeg byte array is as follows:
public byte[] bytesFromBitmap(BitmapImage bit)
{
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bit));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
This is taking my Image taken directly from a webpage and assigned to an Image control like so:
var img = new BitmapImage(new Uri(entity.Image.ImageSrc)); //the entity has been saved in my DB, having been parsed from html
pbImage.Source = img;
This works just fine, I encode the BitmapImage and it saves just fine. But when I retrieve it from the DB and try to display it in another window, I cannot get it to work after trying every example I can see online - all either render nothing, or a black box or a visual mess not at all similar to the image I encoded.
Neither of the following have worked for me:
public BitmapSource GetBMImage(byte[] data)
{
using (var ms = new MemoryStream(data))
{
JpegBitmapDecoder decoder = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource frame = decoder.Frames[0];
return frame;
}
}
public static BitmapImage ImageFromBytes(byte[] imageData)
{
if (imageData == null)
{
return null;
}
else
{
var image = new BitmapImage();
using (var mem = new MemoryStream())
{
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
} //this throws a 'No imaging component suitable to complete this operation was found' exception
Among other uses of memory streams and decoders I just can't get this to work - can anyone help?
I have the following code to convert image to base64:
private void btnSave_Click(object sender, RoutedEventArgs e)
{
StreamResourceInfo sri = null;
Uri uri = new Uri("Checked.png", UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
base64 = System.Convert.ToBase64String(imageBytes);
}
And the following code to get Bitmap image form base 64:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes, 0, fileBytes.Length))
{
ms.Write(fileBytes, 0, fileBytes.Length);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
return bitmapImage;
}
}
So when i convert and deconvert it is blank.
I know that deconverter works, because, when i give him exact string:
string base64="iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAACH0lEQVR42q3WoZKrMBQGYGRkIpHEoY9DMrh1nUGtzxPcGV7gCsTaK3iBCqa2ipmrVqLrWrmytjL3nBwoEGD30ja/6JaSj/wp3SEIXjpUoB+Oeg0zpoR+NsyoDVOgi39cbYHAy4MQTc0wOYZepxRBUkn9UxxEiNnXxyYwd6w/438hSddHJilv1tqv664Shle1DeJaJihPV9uNQ+NWBRK2QVSr+GjtaFzOIpdjKFShnoY+Gv0N0u0OVLexY48NQ+68JchdpQu/o1piVMu6faJdwjNWIAYyl55bqGUtbndO53TzCIpUpCkdlEm+V3J3Ir8r3uops2+FkTmvx832IGJwN97xS/5Ti0LQ/WLwtbxMal2ueAwvc2c8CAgSJip5U4+tKHECMlUzq2UcA9EyROuJi6/71dtzWAfVcq0Jw1CsYh13kDDteVoirE+zWtLVinQ8ZAS5YlVlvRHWfi3pakUQL0OOwmp/W/vN6Gt5zBIkzEezxnCtMJsxDIECTYmhp3bej4HHzaalNMyAnzE0UBKp6Z1Do2pwd3JkAH6CxlTs/bZOZ661yMwhohDLQqREMWz8UAvWoUQleggehG5dSPUbv28GJlnKHGJsqPi7vuG/MGTyCGslOtkCOayrGOa/indajdudb6FUpXoepgiLHIIMriddyzrkMBhGAqlOH4U2hKCT2j0NdU8jFbzpZ3LQlh9srPqEQ1Y9lEP2CVa99KHvH8mnrGGdl9V9AAAAAElFTkSuQmCC";
Which is my Checked.png converted in online converter. It decompreses perfectly.
And this is my base64, which i get by converting:
"/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAkACQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+AXyv978v/rUeV7N+X/1q0FhyFxnlc9vT6d+APcgV2HiL4cePvCGheCvFHizwR4w8L+GfiVo9/wCIvhz4i8ReGda0TQfH3h/S9av/AA3qeueCtX1OxtdP8V6Pp3iLS9U0G+1PQbm/srTWtNv9LnnjvrO4gjAOO0rRtS1zUtP0bRtPv9W1fVr600zS9K0y0nv9S1PUr+eO1sdP0+xtY5bq8vby6mitrW1t4pJ7ieWOGGN5HVS/WND1Xw9qup6Frumajout6JqN7pGs6Nq1lcadqukatptzLZajpmp6deRQ3dhqFhewTWl7ZXUMVza3MMsE8ccqMg/tk/4NKv8Agjy3xm+JkH/BTj9oDwss3wm+DXiC70v9l3QNZtEktfHvxp0Sd7XVvin9mucpc+Hfg9cB7PwxdC1lhu/irIdR0/UbPVfhdeW13yf/AAeM/Fj9iTXf2pvhp8IPg/8ACjwRJ+2H4N02PxJ+1F8dPCpbStUi0bWdGhX4e/CLxnY6TPBpHjPxmdHms/GWpeIfEthc+JPCXhj/AIQTw9o+tyafrms6PpYB/Fiy7Tjn8aKluV2yY/2RRQB7r8CtS+E3h34wfCvxD8efBvib4hfBXRfHnhLVfir4E8G+ILfwv4o8YeALLWLO58UeHtD1+5t7mLTNQ1TSUurSKY/ZJZPN8i31XRLiWLWLL/W48Q/Bf/gmX/wXm/4Jg6V8PfgkPhtqfwYT4ey+EfgFrOleDorLxX+xt8SNA8Jnwz4Ot4fh9pmseE9d8E6x8M2t9Jt9T+HEOveHvD/jvwbY2+l2uq6n4D8Q6Vrd3/kEQxfuYiMcxp3PdB+Fff8A/wAE7v8AgpB+1H/wTJ+Omn/Gv9mzxpLp9veT6ba/Ez4Wa1NdXXwy+L/hayunmPhzxx4eS4ijnmhjuL1dC8UaebXxX4Unvry58P6tZi+1GG7AP9Q3/gpJ+2p+zz/wQi/4JraUnww8MeHNE1Lwp4PsfgV+x58FbcKIvEPju20OSDR9R1i3iaG81Dw34RiSbx98U/Ed3PBe69Ik1nc6w3jPxro7ah/kLfEnx946+L/xB8b/ABV+JviXVvG3xF+I/ivXvG/jrxdrlws+r+JfFfibU7nV9c1nUZQsStdX+o3dxcyCKKG3jMnlW0ENvHFGv6ff8Fgf+CqPxQ/4K0ftQQfHDxdoEnw7+HHgrwxZeCfgx8HY/EDeI7H4f6AUhv8AxNfXeqrY6Tba34q8X+JjcalrmvpoumS3OmWnhnw+8Mtj4YsGH5ReT9PzNAHF6guy4K4wdi5HXrmip9YXbesP+mcfr6UUAdHb+NTFbwQ3Hhnw5qE0MUcT310fEUd1ciKNI0e4Fh4hsrRptqDzJY7WOSeQvNO0szvI0v8AwnEX/QneFf8Av74t/wDmroooAP8AhOIv+hO8K/8Af3xb/wDNXSjxzECD/wAIb4UODnBl8XYPsceLAcH2IPoRRRQByWp6g+p3kl21taWm8KqW1lE0UEUaDaiKZZJriUgcGa6uLi4fjzJnwMFFFAH/2Q=="
My problem is that string which i get as base64 from my code - is incorrect *What i did wrong?*
What about trying:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes))
{
Image streamImage = Image.FromStream(ms);
context.Response.ContentType = "image/jpeg";
streamImage.Save(context.Response.OutputStream, ImageFormat.Jpeg);
return streamImage;
}
}
I agree with Alexei that your code for reading the image in does look a little strange. I've recently written some code for a similar task that I was doing which might point you in the right direction:
string fileContent = null;
/* Check the file actually has some content to display to the user */
if (uploadFile != null && uploadFile.ContentLength > 0)
{
byte[] fileBytes = new byte[uploadFile.ContentLength];
int byteCount = uploadFile.InputStream.Read(fileBytes, 0, (int)uploadFile.ContentLength);
if (byteCount > 0)
{
fileContent = CreateBase64Image(fileBytes);
}
}
private string CreateBase64Image(byte[] fileBytes)
{
Image streamImage;
/* Ensure we've streamed the document out correctly before we commit to the conversion */
using (MemoryStream ms = new MemoryStream(fileBytes))
{
/* Create a new image, saved as a scaled version of the original */
streamImage = ScaleImage(Image.FromStream(ms));
}
using (MemoryStream ms = new MemoryStream())
{
/* Convert this image back to a base64 string */
streamImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return Convert.ToBase64String(ms.ToArray());
}
}
not an answer: more of a long comment ... OP states that decoding code works perfectly fine, also it looks suspicios. Also code assumed to be verified to work on PNG images, but saving code explicitly produces valid JPG with SaveJpeg call...
Your code that creates stream for reading looks strange - you create stream over existing byte array, than write the same bytes into that stream, and that pass that stream without seeking back to 0 to some method.
Potential fix (assuming BitampImage can accept JPG stream):
don't call Write at all as stream already have the bytes you want
set ms.Position = 0 after writing to the stream.
Note: I'm not sure if it is OK to dispose stream that is a source for BitmapImage, you may need to remove using too.
I have a WPF Image with a source assign from picture dialog;
this.imgProduct.Source = new BitmapImage(new Uri(op.FileName));
How can I retieve the source, convert it to byte array and save it into database?
Thank you
You have to convert BitmapImage into the byte[] then save it to the database.
var imageSource = this.imgProduct.Source as BitmapImage;
var stream = imageSource.StreamSource;
Byte[] buffer = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
buffer = br.ReadBytes((Int32)stream.Length);
}
}
// write buffer to the database
P.S. I haven't tested the code but I think it works!
As long as you have access to the image file in op.FileName it would be very easy to get the file content by e.g.
byte[] imageBuffer = File.ReadAllBytes(op.FileName);
If the image is loaded from a file Uri (as in your example) you could also do this:
byte[] imageBuffer = File.ReadAllBytes(image.UriSource.AbsolutePath);
If you only have the BitmapImage without information about the file that it was loaded from (e.g. when it was loaded from a temporary file or a web resource), you would have to encode it by one of WPFs BitmapEncoders:
byte[] imageBuffer;
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream stream = new MemoryStream())
{
encoder.Save(stream);
imageBuffer = stream.GetBuffer();
}
I have a BitmapImage that I'm using in a WPF application, I later want to save it to a database as a byte array (I guess it's the best way), how can I perform this conversion?
Or, alternatively, is there a better way to save a BitmapImage (or any of its base classes, BitmapSource or ImageSource) to a data repository?
To convert to a byte[] you can use a MemoryStream:
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
using(MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
Instead of the JpegBitmapEncoder you can use whatever BitmapEncoder you like as casperOne said.
If you are using MS SQL you could also use a image-Column as MS SQL supports that datatype, but you still would need to convert the BitmapImage somehow.
You will have to use an instance of a class that derives from BitmapEncoder (such as BmpBitmapEncoder) and call the Save method to save the BitmapSource to a Stream.
You would choose the specific encoder depending on the format you want to save the image in.
write it to a MemoryStream, then you can access the bytes from there.
something kinda like this:
public Byte[] ImageToByte(BitmapImage imageSource)
{
Stream stream = imageSource.StreamSource;
Byte[] buffer = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
buffer = br.ReadBytes((Int32)stream.Length);
}
}
return buffer;
}
You can give a formate of bitmap:
Image bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics.FromImage(bmp).CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.PrimaryScreen.Bounds.Size);
MemoryStream m = new MemoryStream();
bmp.Save(m, System.Drawing.Imaging.ImageFormat.Png);
byte[] imageBytes = m.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
Just use a MemoryStream.
byte[] data = null;
using(MemoryStream ms = new MemoryStream())
{
bitmapImage.Save(ms);
data = ms.ToArray();
}
what is the easiest way to translate a Bitmap & Png to string AND BACK AGAIN. Ive been trying to do some saves through memory streams and such but i cant seem to get it to work!
Appearently i wasnt clear,
what i want, is to be able to translate a Bitmap class, with an image in it.. into a system string. from there i want to be able to throw my string around for a bit, and then translate it back into a Bitmap to be displayed in a PictureBox.
Based on #peters answer I've ended up using this:
string bitmapString = null;
using (MemoryStream memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Png);
byte[] bitmapBytes = memoryStream.GetBuffer();
bitmapString = Convert.ToBase64String(bitmapBytes, Base64FormattingOptions.InsertLineBreaks);
}
and
Image img = null;
byte[] bitmapBytes = Convert.FromBase64String(pictureSourceString);
using (MemoryStream memoryStream = new MemoryStream(bitmapBytes))
{
img = Image.FromStream(memoryStream);
}
From bitmap to string:
MemoryStream memoryStream = new MemoryStream();
bitmap.Save (memoryStream, ImageFormat.Png);
byte[] bitmapBytes = memoryStream.GetBuffer();
string bitmapString = Convert.ToBase64String(bitmapBytes, Base64FormattingOptions.InsertLineBreaks);
From string to image:
byte[] bitmapBytes = Convert.FromBase64String(bitmapString);
MemoryStream memoryStream = new MemoryStream(bitmapBytes);
Image image = Image.FromStream(memoryStream);