golang 从windows 剪切板 (剪贴板)中读取bmp图片数据的方法
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图片数据的方法相关推荐
- emwin从外部flash中读取bmp图片显示
在emwin中有提供了一个从外部读取图片数据进行显示的函数,如下: 而且提供了官方例程,不过官方历程中从外部读取是从外部文件系统中进行读取的bmp图片进行显示,官方例程如下 /* ********** ...
- 如何获取windows剪切板中内容
一个简单的获取windows剪切板中文本内容的代码 // 获取剪切板中的内容public static String getClipboardText() {Clipboard clip = Tool ...
- Windows 剪切板的应用——复制浏览器or本地目录图片
一.简述 最近看了windows的剪切板相关的应用代码,于是乎,便想将浏览器中复制的图片保存到本地,经过尝试,通过以下代码完成在浏览器中右键选择复制图片,然后监控键盘事件,当按下Ctrl + v 时保 ...
- windows剪切板api
Windows 剪切板API详解 (一) ChangeClipboardChain 将剪贴的连接从一个句柄转到下一个句柄. BOOL ChangeClipboardChain( HWND hWn ...
- 如何对Windows剪切板里的内容进行取证分析 Windows剪切板取证
前言 无论是在现实中对设备进行取证分析,还是在ctf中做取证类的题目,剪切板里的内容都需要去查看,以免遗漏什么重要信息 剪切板位置 剪切板是计算机操作系统提供的一个临时存储区域,用于在不同应用程序之间 ...
- windows剪切板文本和文件的获取设置
介绍 windows剪切板的内容包含很多不同的格式,例如:CF_TEXT.CF_BITMAP.CF_METAFILEPICT.CF_SYLK.CF_DIF.CF_TIFF.CF_OEMTEXT.CF_ ...
- 写入windows剪切板,粘贴出来乱码
操作windows剪切板,写入正常,粘贴出来时候乱码了. 之前的代码: BOOL CopyStringToClipBoard( HWND hOwner, CString strSource ) {if ...
- matlab复制矢量图形,Matlab4.2b提供了将wmf格式矢量图复制到Windows剪切板.doc
Matlab4.2b提供了将wmf格式矢量图复制到Windows剪切板.doc Matlab 4.2b提供了将wmf格式矢量图复制到Windows剪切板的功能,可以将它直接粘贴到Word文档中而不发生 ...
- windows剪切板的历史记录
windows剪切板的历史记录 最近遇到一件比较坑的事情.当然可能也是我本人粗心大意了吧.但是这种事情难免要发生.比如说你要移动一个比较重要的东西,然后按了ctrl+x,但是之间因为别的事情耽搁了一下 ...
最新文章
- C++与MATLAB数组的存储结构
- TCP的粘包和拆包及Netty中的解决方案
- web前端入门学习 css(4)(盒子模型)
- 【Redis系列】深入浅出Redis主从复制之哨兵模式【实践】
- python 基础(十)
- 基于AVS2的图片容器——TPG:现状与改进之路
- 创建新的option
- Failedto load class org.slf4j.impl.StaticLogger...
- java 方法重载调用_Java方法的定义以及调用、方法重载、可变参数以及递归
- auc 和loss_精确率、召回率、F1 值、ROC、AUC 各自的优缺点是什么?
- MySQL-(1)查看用户权限、(2)用户授权、(3)删除用户权限 语法格式总结
- Word无法读取此文档,文档可能已损坏
- win7 修复计算机 黑屏,Win7系统崩溃不用重做!Win7无法进入桌面黑屏
- 夏昕.深入浅出Hibernate中的第一个例子体会.
- 在线文本加密解密工具
- Hello World with Ant
- EAS BOS序时簿界面排序
- 为什么网站打得开,却ping不通, 网站却打得开
- Quartus之仿真错误#** Error (suppressible): (vsim-19) Failed to access library ‘ ‘ at “ “
- 官方:最好的版本!Python 3.11正式版来了!