i needed to send bitmap into my chat application soo my idea was save it into a temporaty folder and from there upload it like my drag and drop image thats already working. but when it saves the bitmap in windows fileviewer i can see thumbnail but everywhere else its empty any idea where the problem could be or how to do this any better way? thanks in advance.
here is a video so you can better understand ^^ https://youtu.be/p0t2byTRN58
string temp = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).FullName + #"\Luxray\" + #"\clipboardimg.png";
if (File.Exists(temp))
{
File.Delete(temp);
}
BitmapSource bmpSource = Clipboard.GetImage();
MemoryStream ms = new MemoryStream();
FileStream stream = new FileStream(temp, FileMode.Create);
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmpSource));
encoder.Save(stream);
stream.Close();
this code runs right after if statment that checks if clipboard has bitmap inside and ctrl+v was pressed in the video it is after msgbox with "img sent" pops up.
What are you trying to achieve? if you're trying to save a clipboard image to file the below code works for me:
var img = System.Windows.Forms.Clipboard.GetImage();
img.Save(savePath, ImageFormat.Png);
Related
Good day,
I have this code which upload an image to Google drive from file, everything works well:
// Create a new file on Google Drive
using (var fsSource = new FileStream(UploadFileName, FileMode.Open, FileAccess.Read))
{
// Create a new file, with metadata and stream.
var request = service.Files.Create(fileMetadata, fsSource, "image/jpg");
request.Fields = "*";
var results = await request.UploadAsync(CancellationToken.None);
}
Now I want to do some image manipulation before uploading so that I could convert the image to jpeg if the image is in another format (png or bmp for example) or resize the image, so I changed the file to stream for manipulation, I don't want to save it locally again because the code could be used on a website on mobiles, that's why I am saving to stream.
using (MemoryStream ms = new MemoryStream())
{
Image img = Image.FromFile(uploadfileName);
img.Save(ms, ImageFormat.Jpeg);
}
How can I now upload this ms stream to Google Drive?
Thanks for any clue, I'm not an expect in field.
Thanks all for assistance.
The answer suggested by canton7 works:
Just set ms.Position = 0, so that the next read starts reading from the beginning of the stream, then use it in place of your fsSource in your first snippet
I've been working for a few days trying to figure out how to save and load images to and from isolated storage. Yesterday, I finally managed to fix whatever issue I was having with storing them, but now I need to add the image as the icon to a menu item, and I don't know what is wrong with my code:
var image = new System.Windows.Controls.Image();
using(var stream = new IsolatedStorageFileStream((string) (directory + file + ext),
FileMode.Open, IsolatedStorageFile.GetUserStoreForAssembly()))
{
image.Source = (BitmapSource) new PngBitmapDecoder(stream,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOptions.Default).Frames[0];
}
Menu menu = new Menu();
MenuItem item = new MenuItem();
item.Header = file;
item.Icon = image;
menu.Items.Add(item);
The image comes up in the menu as the right size, but it's a blank image. The image file shows the image just fine when I preview it in Windows Photo Viewer.
I'm still pretty new to C# and WPF (only been working with it for 3 months), and I'm looking for a simple solution that doesn't really need to be elegant or generic; it just needs to work.
It figures that I would answer my own question half an hour after asking for help. Scoured the Web for days trying to figure it out, and it just falls in my lap. I just needed to instantiate my stream with the correct FileAccess:
I just replaced
using(var stream = new IsolatedStorageFileStream((string) (directory + file + ext),
FileMode.Open, IsolatedStorageFile.GetUserStoreForAssembly()))
with
using(var stream = IsolatedStorageFile.GetUserStoreForAssembly().OpenFile(
(string) (directory + file + ext), FileMode.Open, FileAccess.Read))
I'm developing a control where user can set an image and i want this this to be as user friendly as possible - so support for copy & paste, drag & drop.
I've got this part working using IDataObjects, testing for fileformats of FileDrop, FileContents (eg from outlook), and bitmap eg:
private void GetImageFromIDataObject(IDataObject myIDO)
{
string[] dataformats = myIDO.GetFormats();
Boolean GotImage = false;
foreach (string df in dataformats)
{
if (df == DataFormats.FileDrop)
{
// code here
}
if (df == DataFormats.Bitmap)
{
// Source of my problem here... this gets & displays image but
// how do I then convert from here ?
ImageSource myIS = Utilities.MyImaging.ImageFromClipboardDib();
ImgPerson.Source = myIS;
}
}
}
The ImageFromClipboard code is Thomas Levesque's as referenced in the answer to this SO question wpf InteropBitmap to bitmap
http://www.thomaslevesque.com/2009/02/05/wpf-paste-an-image-from-the-clipboard/
No matter how I get the image onto ImgPerson, this part is working fine; image displays nicely.
When user presses save I need to convert the image to a bytearray and send to a WCF server which will save to server - as in, reconstruct the bytearray into an image and save it in a folder.
For all formats of drag & drop, copy & paste the image is some form of System.Windows.Media.Imaging.BitmapImage.
Except for those involving the clipboard which using Thomas's code becomes System.Windows.Media.Imaging.BitmapFrameDecode.
If I avoid Thomas's code and use:
BitmapSource myBS = Clipboard.GetImage();
ImgPerson.Source = myBS;
I get a System.Windows.Interop.InteropBitmap.
I can't figure out how to work with these; to get them into a bytearray so I can pass to WCF for reconstruction and saving to folder.
Try this piece of code
public byte[] ImageToBytes(BitmapImage imgSource)
{
MemoryStream objMS = new MemoryStream();
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imgSource));
encoder.Save(objMS);
return objMS.GetBuffer();
}
You can also use JpegBitmapEncoder, BmpBitmapEncoder based on your requirements.
byte[] arr = ImageToBytes(ImgPerson.Source as BitmapImage);
I can't believe I didn't see this SO question but the this is essentially the same as my question:
WPF: System.Windows.Interop.InteropBitmap to System.Drawing.Bitmap
The answer being:
BitmapSource bmpSource = msg.ThumbnailSource as BitmapSource;
MemoryStream ms = new MemoryStream();
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmpSource));
encoder.Save(ms);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(ms);
So similar in execution to Nitesh's answer but crucially, works with an inter-op bitmap.
I'm using the following line of code to open an Image from a file:
pictureBox1.Image = Image.FromFile("test.png");
I expect it to lock the file, load the image to memory, set pictureBox1.Image to the copy in memory, and release the lock. In reality, the lock won't go away until I Dispose() of the Image in memory. I can not release the lock on the file on the harddrive that I am no longer using until I get rid of the file in memory that I am using.
Microsoft's site mentions it in a C#-labeled article, but their solution is written in visual basic, which is useless to me.
In summary:
I want to set pictureBox1.Image to the image stored in "test.png", then let the user edit or delete "test.png" or whatever.
The approach with stream is not correct.
See here https://stackoverflow.com/a/8701748/355264
Correct code from above link:
Image img;
using (var bmpTemp = new Bitmap("image_file_path"))
{
img = new Bitmap(bmpTemp);
}
Or better yet, use a using statement (the code below is otherwise copied from sylon's [deleted] post). This way if the Image.FromStream throws an exception, you can still be assured that the stream is immediately closed.
using (FileStream stream = new FileStream("test.png", FileMode.Open, FileAccess.Read))
{
pictureBox1.Image = Image.FromStream(stream);
}
You can also use a stream to read the image then close the stream.
FileStream stream = new FileStream("test.png", FileMode.Open, FileAccess.Read);
pictureBox1.Image = Image.FromStream(stream);
stream.Close();
The easiest ever way I found is to freeze the object that contains the Source (path to the file). All controls that can contain an image, seem to have a .Source which, if not null, it will lock the file it points to.
Now the trick is to change the Image control to a "read-only" state, which then unlocks the file.
My solution:
private Image CreatePreviewImage()
{
Image ReportImage = new Image();
Uri path = new Uri(#"C:\Folder\Image1.png");
if (File.Exists(path.OriginalString))
{
ReportImage.Name = "Report1";
ReportImage.Source = LoadImageFromFile(path);
}
return ReportImage;
}
public ImageSource LoadImageFromFile(Uri path)
{
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = path;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bitmap.DecodePixelWidth = 900;
bitmap.EndInit();
bitmap.Freeze(); //This is the magic line that releases/unlocks the file.
return bitmap;
}
talking open, read and release
StreamReader streamReader = new StreamReader("picture.png");
Bitmap tmpBitmap = (Bitmap)Bitmap.FromStream(streamReader.BaseStream);
streamReader.Close();
pictureBox1.Image = tmpBitmap;`
I am getting an odd error with Image.save(Stream, Format).
I tried looking around on here for a solution but everyone seems to think the error is from file permissions. That can't be it in my case case the Stream isn't going into a file. My code is below:
MemoryStream Stream = new MemoryStream();
this.Image_Box_1.Image.Save(Stream, System.Drawing.Imaging.ImageFormat.Jpeg);
TI.AlbumCover = Stream.ToArray();
Stream.Close();
TI.AlbumCover is a byte[].
Does anyone have any ideas on what the problem might be?
EDIT:
Ok, so I worked it out. The original file could sometimes come from a jpg file, sometimes from a byte array (part of an id3 tag). The problem was that when the image came from the file, I was closing the stream after creating the image box image. While the image remained visible, the data was no longer available.
Since I also later needed to overwrite that jpg file, I could not simply leave the filestream for it open so I left the rest of my code the same and changed the code to read from the jpg to the following:
FileStream FS = new FileStream(File, FileMode.Open, FileAccess.Read);//Read in the jpg file
Image IMG = Image.FromStream(FS);//Create an image from the file data
MemoryStream MS = new MemoryStream();
IMG.Save(MS, System.Drawing.Imaging.ImageFormat.Jpeg);//Save the image data to a memory stream
byte[] temp = MS.ToArray();//Copy the image data to a byte array
//close the streams
MS.Close();
FS.Close();
return temp; //was originally returning an image
Then after executing this code I change the code that placed the image into the image box to:
try
{
if (this.m_V2Tag.AlbumCover != null)
this.Image_Box_1.Image = Image.FromStream(new MemoryStream(this.m_V2Tag.AlbumCover));
//changed code
else
{
MemoryStream temp = new MemoryStream(this.getFolderJpg()); //create a memory stream from the byte[]. This stream can safely be left open.
this.Image_Box_1.Image = Image.FromStream(temp); // create image and assign it to the image box
}
}
catch
{
this.Image_Box_1.Image = null;
}