golang访问剪切板的通常做法是使用"github.com/atotto/clipboard"库,但是这个库只支持读取文本信息,不支持读取图片信息。
这里实现了这个功能,代码地址如下:
github地址为 https://github.com/liushiyuan/goPaste

使用的win32 api如下

const (cfBITMAP      = 2cfUnicodetext = 13gmemMoveable  = 0x0002
)var (user32                     = syscall.MustLoadDLL("user32")isClipboardFormatAvailable = user32.MustFindProc("IsClipboardFormatAvailable")openClipboard              = user32.MustFindProc("OpenClipboard")closeClipboard             = user32.MustFindProc("CloseClipboard")emptyClipboard             = user32.MustFindProc("EmptyClipboard")getClipboardData           = user32.MustFindProc("GetClipboardData")setClipboardData           = user32.MustFindProc("SetClipboardData")getDC                      = user32.MustFindProc("GetDC")kernel32     = syscall.NewLazyDLL("kernel32")globalAlloc  = kernel32.NewProc("GlobalAlloc")globalFree   = kernel32.NewProc("GlobalFree")globalLock   = kernel32.NewProc("GlobalLock")globalUnlock = kernel32.NewProc("GlobalUnlock")lstrcpy      = kernel32.NewProc("lstrcpyW")libgdi32           = syscall.NewLazyDLL("gdi32.dll")createCompatibleDC = libgdi32.NewProc("CreateCompatibleDC")getObject          = libgdi32.NewProc("GetObjectW")selectObject       = libgdi32.NewProc("SelectObject")getDIBits          = libgdi32.NewProc("GetDIBits")
)type BITMAPINFOHEADER struct {BiSize          uint32BiWidth         int32BiHeight        int32BiPlanes        uint16BiBitCount      uint16BiCompression   uint32BiSizeImage     uint32BiXPelsPerMeter int32BiYPelsPerMeter int32BiClrUsed       uint32BiClrImportant  uint32
}

读取图片信息的主要流程如下
首先用isClipboardFormatAvailable 判断剪切板中的信息类型是否为图片,打开剪切板。

func PasteImg(outputPng bool) ([]byte, error) {runtime.LockOSThread()defer runtime.UnlockOSThread()if formatAvailable, _, err := isClipboardFormatAvailable.Call(cfBITMAP); formatAvailable == 0 {return nil, err}err := waitOpenClipboard()if err != nil {return nil, err}

获取剪切板资源句柄,再通过句柄获取资源对象,从对象中提取图片的长度、宽度、位数,三个信息。

 h, _, err := getClipboardData.Call(cfBITMAP)if h == 0 {_, _, _ = closeClipboard.Call()return nil, err}hdc, _, err := getDC.Call(0)hdcmem, _, err := createCompatibleDC.Call(hdc)selectObject.Call(hdcmem, h)bm := make([]byte, 28)var size uint = 28getObject.Call(h, uintptr(unsafe.Pointer(&size)), uintptr(unsafe.Pointer(&bm[0])))width := binary.LittleEndian.Uint32(bm[4:8])height := binary.LittleEndian.Uint32(bm[8:12])bmBitsPixel := bm[18]

构造bmp信息头,通过getDIBits获取图片内容,a是bmp信息头,b是保存图片数据的缓冲区

 a := new(BITMAPINFOHEADER)a.BiSize = 40a.BiWidth = int32(width)a.BiHeight = int32(height)a.BiPlanes = 1a.BiBitCount = uint16(bmBitsPixel)a.BiSizeImage = (width*uint32(bmBitsPixel) + 31) / 32 * 4 * heightb := make([]byte, a.BiSizeImage)getDIBits.Call(hdc, h, 0, uintptr(height), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(a)), 0)

按照bmp文件格式,构造数据

 w := bytes.NewBuffer([]byte{})w.Write([]byte{0x42, 0x4d})bytesBuffer := bytes.NewBuffer([]byte{})binary.Write(bytesBuffer, binary.LittleEndian, a.BiSizeImage+54)w.Write(bytesBuffer.Bytes())temp := make([]byte, 8)temp[4] = 0x36w.Write(temp)w.Write([]byte{0x28, 0x00, 0x00, 0x00})bytesBuffer.Reset()binary.Write(bytesBuffer, binary.LittleEndian, a.BiWidth)binary.Write(bytesBuffer, binary.LittleEndian, a.BiHeight)binary.Write(bytesBuffer, binary.LittleEndian, a.BiPlanes)binary.Write(bytesBuffer, binary.LittleEndian, a.BiBitCount)var temp1 uint32temp1 = 0binary.Write(bytesBuffer, binary.LittleEndian, temp1)binary.Write(bytesBuffer, binary.LittleEndian, temp1)w.Write(bytesBuffer.Bytes())bytesBuffer.Reset()temp = make([]byte, 16)w.Write(temp)w.Write(b)

基本上使用png图片格式居多,这个可以根据需要将bmp转为png

func bmp2png(w *bytes.Buffer) ([]byte, error) {var err errorvar src image.Imagesrc, err = bmp.Decode(w)if err != nil {return nil, err}out := bytes.NewBuffer([]byte{})png.Encode(out, src)return out.Bytes(), nil
}

golang 从windows 剪切板 (剪贴板)中读取bmp图片数据的方法相关推荐

  1. emwin从外部flash中读取bmp图片显示

    在emwin中有提供了一个从外部读取图片数据进行显示的函数,如下: 而且提供了官方例程,不过官方历程中从外部读取是从外部文件系统中进行读取的bmp图片进行显示,官方例程如下 /* ********** ...

  2. 如何获取windows剪切板中内容

    一个简单的获取windows剪切板中文本内容的代码 // 获取剪切板中的内容public static String getClipboardText() {Clipboard clip = Tool ...

  3. Windows 剪切板的应用——复制浏览器or本地目录图片

    一.简述 最近看了windows的剪切板相关的应用代码,于是乎,便想将浏览器中复制的图片保存到本地,经过尝试,通过以下代码完成在浏览器中右键选择复制图片,然后监控键盘事件,当按下Ctrl + v 时保 ...

  4. windows剪切板api

    Windows 剪切板API详解 (一) ChangeClipboardChain  将剪贴的连接从一个句柄转到下一个句柄.  BOOL ChangeClipboardChain(  HWND hWn ...

  5. 如何对Windows剪切板里的内容进行取证分析 Windows剪切板取证

    前言 无论是在现实中对设备进行取证分析,还是在ctf中做取证类的题目,剪切板里的内容都需要去查看,以免遗漏什么重要信息 剪切板位置 剪切板是计算机操作系统提供的一个临时存储区域,用于在不同应用程序之间 ...

  6. windows剪切板文本和文件的获取设置

    介绍 windows剪切板的内容包含很多不同的格式,例如:CF_TEXT.CF_BITMAP.CF_METAFILEPICT.CF_SYLK.CF_DIF.CF_TIFF.CF_OEMTEXT.CF_ ...

  7. 写入windows剪切板,粘贴出来乱码

    操作windows剪切板,写入正常,粘贴出来时候乱码了. 之前的代码: BOOL CopyStringToClipBoard( HWND hOwner, CString strSource ) {if ...

  8. matlab复制矢量图形,Matlab4.2b提供了将wmf格式矢量图复制到Windows剪切板.doc

    Matlab4.2b提供了将wmf格式矢量图复制到Windows剪切板.doc Matlab 4.2b提供了将wmf格式矢量图复制到Windows剪切板的功能,可以将它直接粘贴到Word文档中而不发生 ...

  9. windows剪切板的历史记录

    windows剪切板的历史记录 最近遇到一件比较坑的事情.当然可能也是我本人粗心大意了吧.但是这种事情难免要发生.比如说你要移动一个比较重要的东西,然后按了ctrl+x,但是之间因为别的事情耽搁了一下 ...

最新文章

  1. C++与MATLAB数组的存储结构
  2. TCP的粘包和拆包及Netty中的解决方案
  3. web前端入门学习 css(4)(盒子模型)
  4. 【Redis系列】深入浅出Redis主从复制之哨兵模式【实践】
  5. python 基础(十)
  6. 基于AVS2的图片容器——TPG:现状与改进之路
  7. 创建新的option
  8. Failedto load class org.slf4j.impl.StaticLogger...
  9. java 方法重载调用_Java方法的定义以及调用、方法重载、可变参数以及递归
  10. auc 和loss_精确率、召回率、F1 值、ROC、AUC 各自的优缺点是什么?
  11. MySQL-(1)查看用户权限、(2)用户授权、(3)删除用户权限 语法格式总结
  12. Word无法读取此文档,文档可能已损坏
  13. win7 修复计算机 黑屏,Win7系统崩溃不用重做!Win7无法进入桌面黑屏
  14. 夏昕.深入浅出Hibernate中的第一个例子体会.
  15. 在线文本加密解密工具
  16. Hello World with Ant
  17. EAS BOS序时簿界面排序
  18. 为什么网站打得开,却ping不通, 网站却打得开
  19. Quartus之仿真错误#** Error (suppressible): (vsim-19) Failed to access library ‘ ‘ at “ “
  20. 官方:最好的版本!Python 3.11正式版来了!

热门文章

  1. 产品经理如何开好需求评审会
  2. zedgraph显示最小刻度_ZedGraph 控件各属性以及示例
  3. mac设计师系列 Adobe “全家桶” 15款设计软件 值得收藏!
  4. 手机开热点显示互联网无服务器,win10热点无互联网连接的具体解决办法【图文】...
  5. 【SSH】--SSH框架简介
  6. PostgreSQL学习手册
  7. 下载网页所有图片的最简单的方法
  8. win11任务管理器怎么打开?win11任务管理器打开的技巧方法
  9. js 为label标签和div标签赋值
  10. register关键字