views:

209

answers:

3

I want to know whether it is possible to programmatically change an image encoding on the fly without saving the image to a file?

Use Case: When the user copies a binary image from a source, would it be possible to change the image encoding from binary to base64?

+3  A: 

You could change the encoding of an image without saving it to a file, but not without saving it to a variable in your code. The Clipboard class basically just has some Get and Set methods. The only way to change what's in the clipboard is to call one of the Get methods into a local variable, change whatever it is you just got, and then call one of the Set methods, passing in your changed object. This results in a changed clipboard object, but not without the intermediate step of "saving" it to a variable.

Clipboard does not expose any methods for directly manipulating the memory of the object in the clipboard. Even if such a method were exposed, changing the encoding of an image from binary to Base64 involves fundamentally changing all of the memory, so there wouldn't be much value to it.

Update: here's a method that will take an image from the clipboard, convert it to a base64 string, and put it back into the clipboard:

if (Clipboard.ContainsImage())
{
    using (MemoryStream memory = new MemoryStream())
    {
        using (Image img = Clipboard.GetImage())
        {
            img.Save(memory, img.RawFormat);
        }
        string base64 = Convert.ToBase64String(memory.ToArray());
        Clipboard.SetText(base64);
    }
}

And you'll need these two using statements:

using System.IO;
using System.Windows.Forms;

It's untested (because it's past my bedtime), but it should work. It does involve the use of local variables, but this is unavoidable (as well as normal).

MusiGenesis
A: 

Using the new ClipBoard class in WPF

The below example reads a stream from a file but you could use any stream

        var image = new BitmapImage();

        image.BeginInit();
        image.StreamSource = File.Open("image.png", FileMode.Open);
        image.EndInit();

        System.Windows.Clipboard.SetImage(image);

http://msdn.microsoft.com/en-us/library/system.windows.clipboard.setimage.aspx

Simon
The Clipboard class isn't new or unique to WPF. It's been in .Net since 1.0.
MusiGenesis
I made the destiction because CLipboard from WPF is a different class with a different API. For example System.Windows.Clipboard.SetImage takes a BitmapSource while System.Windows.Forms.Clipboard.SetImage takes an Image
Simon
@Simon: I think I need glasses. I read your first line as the imperative "Use the new ClipBoard class in WPF", implying that it could do something the old Clipboard class couldn't do. My bad.
MusiGenesis
A: 

I think that you might be asking how to intercept the copy operation and replace the logical contents of the clipboard with new contents, all from some background app, rather than how to replace the memory bytes allocated to the original copy operation.

If that's the intention, you should look for Win32 API calls to hook into the clipboard so that the background app can process the data copied before it is available for paste.

This article might get you going:

http://www.radsoftware.com.au/articles/clipboardmonitor.aspx

uosɐſ