vscode-markdown icon indicating copy to clipboard operation
vscode-markdown copied to clipboard

Paste image from clipboard as base64

Open NewUserHa opened this issue 5 years ago • 16 comments
trafficstars

Proposal

Adding pictures in Markdown is very useful at most time. But the expired or private image URL could be a problem.

We should have a way to keep images in local files:

Paste / Convert image from clipboard ~~or URL~~ to Base64 data URL or local file.

Tasks

VS Code is also interested in this topic. They appear to have another way to solve it.

Our approach (Clipboard API) is blocked by the upstream.

NewUserHa avatar Aug 28 '20 16:08 NewUserHa

There are already many extensions dealing with Markdown images, e.g. Paste Image. It is more suitable as a feature request for those extensions.

yzhang-gh avatar Aug 28 '20 17:08 yzhang-gh

Cool! Very useful information.

Thanks for your replay.

NewUserHa avatar Aug 28 '20 17:08 NewUserHa

But it does not support encoding to base64. https://github.com/mushanshitiancai/vscode-paste-image/issues/74

Shall we reconsider it? The repo seems inactive for some time already

NewUserHa avatar Aug 28 '20 18:08 NewUserHa

I can leave this open as a feature request and see what others think of it.

yzhang-gh avatar Aug 29 '20 00:08 yzhang-gh

I like this idea.

Paste Image works fine, but it would be nice to name the files after the section headers as well as time-stamped. Might also be nice to have the key binding as Ctrl+V instead of Ctrl+Alt+V if possible.

Similarly #522 for pasting from excel sounds nice to have.

gavbarnett avatar Feb 08 '21 16:02 gavbarnett

Generally pasting any file I think should just copy it locally.

sudo code

Pastefunction(paste_object):
   select (paste_object.type)
      case image_type: image_paste() //create image locally (options for file type, size, name)
      case excel_type: excel_paste() //create table
      case file_type: file_paste() //copy file locally
      case ...

gavbarnett avatar Feb 09 '21 10:02 gavbarnett

For anyone who interested in application-agnostic solution check this script: https://github.com/pavlexander/imageAsBase64/blob/main/powershell/pasteImageAsB64.ps1

Add-Type -Assembly PresentationCore

Add-Type -TypeDefinition '
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace KeyLogger {
  public static class Program {
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static HookProc hookProc = HookCallback;
    private static IntPtr hookId = IntPtr.Zero;
    private static int keyCode = 0;
    [DllImport("user32.dll")]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
    [DllImport("user32.dll")]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);
    [DllImport("user32.dll")]
    private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
    public static int WaitForKey() {
      hookId = SetHook(hookProc);
      Application.Run();
      UnhookWindowsHookEx(hookId);
      return keyCode;
    }
    private static IntPtr SetHook(HookProc hookProc) {
      IntPtr moduleHandle = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
      return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, moduleHandle, 0);
    }
    private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
      if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
        keyCode = Marshal.ReadInt32(lParam);
        Application.Exit();
      }
      return CallNextHookEx(hookId, nCode, wParam, lParam);
    }
  }
}
' -ReferencedAssemblies System.Windows.Forms

function GetImageFromClipboard(){
	$img = get-clipboard -format image
	
	if ($img -eq $null) {
		return ""
	}
	
	$memoryStream = New-Object System.IO.MemoryStream
	$img.save($memoryStream, [System.Drawing.Imaging.ImageFormat]::Png)
	$bytes = $memoryStream.ToArray()
	$memoryStream.Flush()
	$memoryStream.Dispose()
	$iconB64 = [convert]::ToBase64String($bytes)

	return $iconB64
}

while ($true) {
    $key = [System.Windows.Forms.Keys][KeyLogger.Program]::WaitForKey();
	#Write-Host $key
    if ($key -eq "Pause") {
		$b64Image = GetImageFromClipboard
		if (![string]::IsNullOrEmpty($b64Image)) {
			$valueToPrint = "![Img X](data:image/png;base64,${b64Image})"		
			Set-Clipboard -Value $valueToPrint
			[System.Windows.Forms.SendKeys]::SendWait("^{v}") 
			Write-Host 'Sent'
		}
		else {
			Write-Host 'No image found'
		}
    }
}

You can use it with any other application of your choice, not just vscode. Though, I agree that having this functionality as part of applications' standard tooling would be more convenient and bulletproof.

p.s. check the readme for known limitations.

pavlexander avatar Mar 01 '21 14:03 pavlexander

i would like it please add it.

NULL0B avatar Apr 05 '21 00:04 NULL0B

Apart of base64 as an option to provide a local folder (eg. "./images") so all images are saved into the folder when pasted/dragged and dropped. In additional when I paste images (mostly they are screenshots) I ussualy need to rename them. And I really like how it is done in the following VS2019 extension (https://github.com/madskristensen/MarkdownEditor). Or it could be done straight from the md file.

fairking avatar Apr 26 '21 18:04 fairking

really useful if we could paste an image (image file or file clip)to markdown file and save it to folder of /image/${currentFileName}/

heartacker avatar Aug 21 '21 11:08 heartacker

I'm afraid we have to wait for the upstream.

We cannot take any native code, otherwise, #996 will be impaired.

VS Code's Clipboard API only supports text for now due to the limitations of the Web API. (https://github.com/microsoft/vscode/issues/77790)

Lemmingh avatar Oct 04 '21 06:10 Lemmingh

If anyone is interested, I recently made a vscode extension to paste images directly from clipboard to base64, the reason is that some companies still prefer to have the images in the same MD file. You can check it out in the Marketplace

voyagerDevil avatar Jul 16 '23 13:07 voyagerDevil

If anyone is interested, I recently made a vscode extension to paste images directly from clipboard to base64, the reason is that some companies still prefer to have the images in the same MD file. You can check it out in the Marketplace

Agreed. Having images scattered all over the place can be annoying, it's not so much the adding them, it's the subsequent managing/updating, and dreaming up appropriate names when all you want to do is illustrate some point in a readme with a screenshot.

keeely avatar Nov 03 '23 11:11 keeely

I can leave this open as a feature request and see what others think of it.

I've been searching for a free markdown editor that handles base64 encoding on image copy-paste and I don't believe there is a single free one. There are web-based ones: CKEditor, Toast UI editor, but they require some fiddling to create standalone applications. You can usually use the online demos but pasting text into a web page is not always desirable.

Markdown all-in-one seems tantalisingly close to providing this functionality, and even teases us with an option for inline base64 for printing to html. I hope you'll consider adding this as well.

keeely avatar Nov 03 '23 12:11 keeely

It looks like there are some interesting extensions e.g., ClipImage64 which can be used in company with this extension. (And Markdown Paste if you do not want base64.)


Oops sorry, just realized it has been mentioned above

If anyone is interested, I recently made a vscode extension to paste images directly from clipboard to base64, the reason is that some companies still prefer to have the images in the same MD file. You can check it out in the Marketplace

yzhang-gh avatar Nov 04 '23 04:11 yzhang-gh