Copying an Image to The Clipboard from Command Line

Copy image data to clipboard on windows

Short anwser. You can't. I guess you best/only option is twapi.

The tk's clipboard command on Windows works for text only. As you can read in the source file of windows's clipboard there are not options for images, just for text.

How can I copy the output of a command directly into my clipboard?

One way of doing it follows:

  1. Install xclip, such as:

    sudo apt-get install xclip

  2. Pipe the output into xclip to be copied into the clipboard:

    cat file | xclip

  3. Paste the text you just copied into a X application:

    xclip -o

To paste somewhere else other than an X application, such as a text area of a web page in a browser window, use:

cat file | xclip -selection clipboard

Consider creating an alias:

alias "c=xclip"
alias "v=xclip -o"

To see how useful this is, imagine I want to open my current path in a new terminal window (there may be other ways of doing it like Ctrl+T on some systems, but this is just for illustration purposes):

Terminal 1:
pwd | c

Terminal 2:
cd `v`

Notice the ` ` around v. This executes v as a command first and then substitutes it in-place for cd to use.

Only copy the content to the X clipboard

cat file | xclip

Copying an image to the clipboard from command line

Have a look at xclip, especially at xclip-copyfile and xclip-pastefile.

  xclip -i < yourfile.png

How to copy an RGBA image to Windows' Clipboard

At least in my experience, trying to transfer png data with a BITMAPV5HEADER is nearly a complete loss, unless you're basically planning on using it strictly as an internal format.

One strategy that does work at least for a fair number of applications, is to register the PNG clipboard format, and just put the contents of a PNG file into the clipboard (with no other header). Code would look something like this:

bool copyBitmapIntoClipboard(Window & window, const Bitmap & in) {
// this section is my code for creating a png file
StreamWrite stream = StreamWrite::asBufferCreate();
in.savePng(stream);
uint64 bufSize = 0;
char * buf = stream._takeBuffer(bufSize, false);
// "buf" <-- contains the PNG payload
// "bufSize" <-- is the size of this payload

HGLOBAL gift = GlobalAlloc(GMEM_MOVEABLE, bufSize);
if (gift == NULL)
return false;

HWND win = window.getWindowHandle();
if (!OpenClipboard(win)) {
GlobalFree(gift);
return false;
}
EmptyClipboard();

auto fmt = RegisterClipboardFormat("PNG"); // or `L"PNG", as applicable

void * giftLocked = GlobalLock(gift);
if (giftLocked) {
memcpy((char*)giftLocked, buf, bufSize);
}
GlobalUnlock(gift);

SetClipboardData(fmt, gift);

CloseClipboard();
return true;
}

I've used code like this with, and successfully pasted the contents into recent versions of at least LibreOffice Write and Calc, MS Word, and Paint.Net.

This is also the format Chrome (for one example) will produce as the first (preferred) format if you tell it to copy a bitmap.

On the other hand, FireFox produces a whole plethora of formats, but not this one. It will produce a CF_DIBV5, but at least if memory serves, it has pre-multiplied alpha (or maybe it loses alpha completely--I don't remember for sure. Doesn't preserve it as you'd want anyway).

Gimp will accept 32-bit RGB format DIB, with alpha in the left-over byte, and make use of that alpha. For better or worse, as far as I've been able to figure out that's about the only thing that works to paste something into Gimp with its alpha preserved (not pre-multiplied).

Notes

  • As versions are updated, the formats they support may well change, so even though (for example) PNG didn't work with Gimp the last time I tried, it might now.

  • You can add the same data into the clipboard in different formats. You want to start from the "best" format (the one that preserves the data most faithfully), and work your way down to the worst. So when you do a copy, you might want to do PNG, then RGB with an alpha channel, then CF_BITMAP (which will pre-multiply alpha, but may still be better than nothing).

How to copy a file/image to the clipboard in Linux using Python

I found a way to do this using a shell command:

os.system(f"xclip -selection clipboard -t image/png -i {path + '/image.png'}")

It's less than ideal but it does the job.



Related Topics



Leave a reply



Submit