| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 127 人关注过本帖
标题:希望实现将指定jpg文件载入win10系统粘贴板,并进行诸如旋转180度,高度缩小 ...
只看楼主 加入收藏
shschy
Rank: 2
等 级:论坛游民
帖 子:142
专家分:45
注 册:2022-3-13
结帖率:39.13%
收藏
 问题点数:10 回复次数:6 
希望实现将指定jpg文件载入win10系统粘贴板,并进行诸如旋转180度,高度缩小xx,宽度缩小xx,再旋转180度
希望实现将指定jpg文件载入win10系统粘贴板,并进行诸如旋转180度,高度缩小xx,宽度缩小xx,再旋转180度
(1)以下第一步载入到win10系统粘贴板就报错,
(2)后面旋转180度,高度缩小xx,宽度缩小xx,再旋转180度,保存操作查到的代码各种报错。
下面是将"D:\01\clipboard_001.jpg"载入操作系统粘贴板的代码,其余代码因为也报错,暂不张贴。
谢谢!

LOCAL lcImagePath
lcImagePath = "D:\01\clipboard_001.jpg"

IF NOT FILE(lcImagePath)
    MESSAGEBOX("图片不存在:" + lcImagePath, 16, "错误")
    RETURN
ENDIF

* 声明API
DECLARE INTEGER OpenClipboard IN user32.dll INTEGER hwnd
DECLARE INTEGER EmptyClipboard IN user32.dll
DECLARE INTEGER CloseClipboard IN user32.dll
DECLARE INTEGER SetClipboardData IN user32.dll INTEGER uFormat, INTEGER hMem
DECLARE INTEGER GlobalAlloc IN kernel32.dll INTEGER uFlags, INTEGER dwBytes
DECLARE INTEGER GlobalLock IN kernel32.dll INTEGER hMem
DECLARE INTEGER GlobalUnlock IN kernel32.dll INTEGER hMem
DECLARE INTEGER GetFileSize IN kernel32.dll INTEGER hFile, INTEGER lpFileSizeHigh
DECLARE INTEGER CreateFile IN kernel32.dll STRING lpFileName, INTEGER dwDesiredAccess, ;
    INTEGER dwShareMode, INTEGER lpSecurityAttributes, INTEGER dwCreationDisposition, ;
    INTEGER dwFlagsAndAttributes, INTEGER hTemplateFile
DECLARE INTEGER ReadFile IN kernel32.dll INTEGER hFile, STRING @lpBuffer, INTEGER nNumberOfBytesToRead, ;
    INTEGER @lpNumberOfBytesRead, INTEGER lpOverlapped
DECLARE INTEGER CloseHandle IN kernel32.dll INTEGER hObject

* 打开剪贴板
IF OpenClipboard(0) = 0
    MESSAGEBOX("打开剪贴板失败", 16)
    RETURN
ENDIF
EmptyClipboard()

* 读取图片文件
hFile = CreateFile(lcImagePath, 1, 3, 0, 3, 128, 0)
IF hFile = -1
    MESSAGEBOX("打开文件失败", 16)
    CloseClipboard()
    RETURN
ENDIF

nFileSize = GetFileSize(hFile, 0)
cBuffer = REPLICATE(CHR(0), nFileSize)
ReadFile(hFile, @cBuffer, nFileSize, @nReadBytes, 0)
CloseHandle(hFile)

* 写入剪贴板
hGlobal = GlobalAlloc(64, nFileSize)
lpGlobal = GlobalLock(hGlobal)
SYS(2600, lpGlobal, nFileSize, cBuffer)
GlobalUnlock(hGlobal)
SetClipboardData(8, hGlobal)

* 关闭剪贴板
CloseClipboard()

* 清理
CLEAR DLLS
MESSAGEBOX("图片已载入剪贴板!", 64)
SET SAFETY ON
RETURN
搜索更多相关主题的帖子: 载入 dll INTEGER 旋转 缩小 
3 天前 02:45
sych
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:7
帖 子:454
专家分:726
注 册:2019-10-11
收藏
得分:0 
Public Declare Function GdipImageRotateFlip Lib "gdiplus" (ByVal Image As Long, ByVal rfType As RotateFlipType) As GpStatus
    RotateNoneFlipNone = 0, // 不旋转不翻转
    Rotate90FlipNone = 1, // 旋转90度不翻转
    Rotate180FlipNone = 2, // 旋转180度不翻转
    Rotate270FlipNone = 3, // 旋转270度不翻转
    RotateNoneFlipX = 4, // 不旋转x向翻转
    Rotate90FlipX = 5, // 旋转90度x向翻转
    Rotate180FlipX = 6, // 旋转180度x向翻转
    Rotate270FlipX = 7, // 旋转270度x向翻转
Declare Long GdipDrawImageRectI in GdiPlus.dll Long graphics, Long image, long x, long y, long width, long height
    把原图变化到多大(后两个参数),复制到新图哪个位置(前两个参数)
3 天前 10:12
schtg
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:Usa
等 级:贵宾
威 望:67
帖 子:2361
专家分:4878
注 册:2012-2-29
收藏
得分:0 
回复 2楼 sych
学习啦,谢谢!
前天 07:17
shschy
Rank: 2
等 级:论坛游民
帖 子:142
专家分:45
注 册:2022-3-13
收藏
得分:0 
打开画图工具后,执行ctrl+v,提示“剪贴板上的信息无法插入画图”
在VFP9表单的command控件click事件里写如下代码,提示“截图已旋转成功并写回剪贴板”,但打开画图工具后,执行ctrl+v,提示“剪贴板上的信息无法插入画图”
LOCAL nGdiplusToken, hImage, nStatus, oClipboard
LOCAL Rotate180FlipNone, GP_OK, GDIP_S_OK
LOCAL lcGdiplusInput, nVersion

* -------------------------- 1. 修正API声明和常量 --------------------------
* GDI+初始化/终止函数(补充结构体参数的正确定义)
DECLARE INTEGER GdiplusStartup IN gdiplus;
    INTEGER @token, STRING @input, STRING @output
DECLARE INTEGER GdiplusShutdown IN gdiplus INTEGER token

* 图像旋转函数
DECLARE INTEGER GdipImageRotateFlip IN gdiplus;
    INTEGER hImage, INTEGER rfType

* 剪贴板/位图相关API
DECLARE INTEGER OpenClipboard IN user32 INTEGER hwnd
DECLARE INTEGER GetClipboardData IN user32 INTEGER uFormat
DECLARE INTEGER CloseClipboard IN user32
DECLARE INTEGER DeleteObject IN gdi32 INTEGER hObject
DECLARE INTEGER EmptyClipboard IN user32
DECLARE INTEGER SetClipboardData IN user32 INTEGER uFormat, INTEGER hMem

* GDI+位图转换API
DECLARE INTEGER GdipCreateBitmapFromHBITMAP IN gdiplus;
    INTEGER hBitmap, INTEGER hPalette, INTEGER @hImage
DECLARE INTEGER GdipDisposeImage IN gdiplus INTEGER hImage
DECLARE INTEGER GdipCreateHBITMAPFromBitmap IN gdiplus;
    INTEGER hImage, INTEGER @hBitmap, INTEGER BackgroundColor

* 常量定义
#DEFINE CF_BITMAP 2          && 剪贴板位图格式
#DEFINE GDIP_S_OK 0         && GDI+操作成功返回值
Rotate180FlipNone = 2       && 旋转180度不翻转

* -------------------------- 2. 正确初始化GdiplusStartupInput结构体 --------------------------
* GdiplusStartupInput结构体结构(共16字节):
* 偏移0-3:GdiplusVersion(UINT32,必须=1)
* 偏移4-7:DebugEventCallback(DWORD,=0)
* 偏移8-11:SuppressBackgroundThread(BOOL,=0)
* 偏移12-15:SuppressExternalCodecs(BOOL,=0)
nVersion = 1
lcGdiplusInput = ;
    BINTOC(nVersion, "4RS") + ;  && 版本号设为1(4字节,小端序)
    REPLICATE(CHR(0), 12)        && 其余字段填0

nGdiplusToken = 0
nStatus = GdiplusStartup(@nGdiplusToken, @lcGdiplusInput, 0)
IF nStatus <> GDIP_S_OK
    MESSAGEBOX("GDI+初始化失败!错误码:" + ALLTRIM(STR(nStatus)), 16, "错误")
    * 额外排查:检查gdiplus.dll是否存在
    IF !FILE("C:\Windows\SysWOW64\gdiplus.dll") AND !FILE("C:\Windows\System32\gdiplus.dll")
        MESSAGEBOX("未找到gdiplus.dll!请确认系统已安装GDI+组件", 16, "提示")
    ENDIF
    RETURN
ENDIF

* -------------------------- 3. 读取剪贴板中的截图 --------------------------
hImage = 0
hBitmap = 0
IF OpenClipboard(Thisform.HWnd) = 1
    hBitmap = GetClipboardData(CF_BITMAP)
    IF hBitmap <> 0
        nStatus = GdipCreateBitmapFromHBITMAP(hBitmap, 0, @hImage)
        IF nStatus <> GDIP_S_OK
            MESSAGEBOX("剪贴板无有效截图!错误码:" + ALLTRIM(STR(nStatus)), 16, "提示")
            CloseClipboard()
            GdiplusShutdown(nGdiplusToken)
            RETURN
        ENDIF
    ELSE
        MESSAGEBOX("剪贴板无位图数据!", 16, "提示")
        CloseClipboard()
        GdiplusShutdown(nGdiplusToken)
        RETURN
    ENDIF
    CloseClipboard()
ELSE
    MESSAGEBOX("无法打开剪贴板!", 16, "错误")
    GdiplusShutdown(nGdiplusToken)
    RETURN
ENDIF

* -------------------------- 4. 执行180度旋转 --------------------------
nStatus = GdipImageRotateFlip(hImage, Rotate180FlipNone)
IF nStatus <> GDIP_S_OK
    MESSAGEBOX("图像旋转失败!错误码:" + ALLTRIM(STR(nStatus)), 16, "错误")
    GdipDisposeImage(hImage)
    DeleteObject(hBitmap)
    GdiplusShutdown(nGdiplusToken)
    RETURN
ENDIF

* -------------------------- 5. 将旋转后的图像写回剪贴板 --------------------------
hNewBitmap = 0
nStatus = GdipCreateHBITMAPFromBitmap(hImage, @hNewBitmap, 0xFFFFFFFF)  && 白色背景
IF nStatus = GDIP_S_OK
    OpenClipboard(Thisform.HWnd)
    EmptyClipboard()  
    SetClipboardData(CF_BITMAP, hNewBitmap)  
    CloseClipboard()
    DeleteObject(hNewBitmap)
ENDIF

* -------------------------- 6. 释放资源 --------------------------
GdipDisposeImage(hImage)      
DeleteObject(hBitmap)         
GdiplusShutdown(nGdiplusToken)

MESSAGEBOX("截图已旋转180度并写回剪贴板!", 64, "成功")

以下是引用sych在2025-12-11 10:12:32的发言:

Public Declare Function GdipImageRotateFlip Lib "gdiplus" (ByVal Image As Long, ByVal rfType As RotateFlipType) As GpStatus
    RotateNoneFlipNone = 0, // 不旋转不翻转
    Rotate90FlipNone = 1, // 旋转90度不翻转
    Rotate180FlipNone = 2, // 旋转180度不翻转
    Rotate270FlipNone = 3, // 旋转270度不翻转
    RotateNoneFlipX = 4, // 不旋转x向翻转
    Rotate90FlipX = 5, // 旋转90度x向翻转
    Rotate180FlipX = 6, // 旋转180度x向翻转
    Rotate270FlipX = 7, // 旋转270度x向翻转
Declare Long GdipDrawImageRectI in GdiPlus.dll Long graphics, Long image, long x, long y, long width, long height
    把原图变化到多大(后两个参数),复制到新图哪个位置(前两个参数)

昨天 03:14
sych
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:7
帖 子:454
专家分:726
注 册:2019-10-11
收藏
得分:0 
* -------------------------- 5. 将旋转后的图像写回剪贴板 --------------------------
DECLARE Long CopyImage IN WIN32API Long hImage, Long, Long, Long , Long
hNewBitmap = 0
nStatus = GdipCreateHBITMAPFromBitmap(hImage, @hNewBitmap, 0xFFFFFFFF)  && 白色背景
IF nStatus = GDIP_S_OK
    hBitmap=copyImage(hNewBitmap,0,0,0,0)
    OpenClipboard(Thisform.HWnd)
    EmptyClipboard()  
    SetClipboardData(CF_BITMAP, hBitmap)  
    CloseClipboard()
    DeleteObject(hNewBitmap)
ENDIF
13 小时前
foxfans
Rank: 5Rank: 5
等 级:贵宾
威 望:15
帖 子:129
专家分:375
注 册:2021-10-23
收藏
得分:0 
以前玩过类似的功能,OpenClipboard CopyImage SetClipboardData 得判断返回值,特别是SetClipboardData,失败的话hBitmap也得释放,要不有概率发生泄漏问题,甚至会破坏当前剪切板功能。
图片附件: 游客没有浏览图片的权限,请 登录注册



[此贴子已经被作者于2025-12-14 16:37编辑过]

4 小时前
shschy
Rank: 2
等 级:论坛游民
帖 子:142
专家分:45
注 册:2022-3-13
收藏
得分:0 
如何在按钮控件的click事件中直接实现将粘贴板里的截图旋转180度?
如何在按钮控件的click事件中直接实现将粘贴板里的截图旋转180度?
以下代码无法实现
以下是引用sych在2025-12-14 07:26:58的发言:

* -------------------------- 5. 将旋转后的图像写回剪贴板 --------------------------
DECLARE Long CopyImage IN WIN32API Long hImage, Long, Long, Long , Long
hNewBitmap = 0
nStatus = GdipCreateHBITMAPFromBitmap(hImage, @hNewBitmap, 0xFFFFFFFF)  && 白色背景
IF nStatus = GDIP_S_OK
    hBitmap=copyImage(hNewBitmap,0,0,0,0)
    OpenClipboard(Thisform.HWnd)
    EmptyClipboard()  
    SetClipboardData(CF_BITMAP, hBitmap)  
    CloseClipboard()
    DeleteObject(hNewBitmap)
ENDIF

53 分钟前
快速回复:希望实现将指定jpg文件载入win10系统粘贴板,并进行诸如旋转180度,高 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017463 second(s), 10 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved