You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows 11下如何将带透明通道的PNG图片保存至剪贴板?

Windows 11 下保留透明背景复制PNG到剪贴板的原生解决方案

问题根源

你当前使用的System.Windows.Forms.Clipboard.SetImage方法仅将图像以Bitmap格式存入剪贴板,Bitmap本身不支持Alpha通道的透明信息,导致背景被替换为灰色或白色。而手动复制时,系统会同时向剪贴板写入PNG原生格式数据,支持透明的应用会优先读取该格式,因此能保留透明效果。

PowerShell 原生解决方案

通过直接调用Windows剪贴板API,将PNG文件的原始字节数据以CF_PNG格式存入剪贴板,确保透明信息完整保留:

Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.IO;

public class ClipboardHelper {
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool OpenClipboard(IntPtr hWndNewOwner);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool EmptyClipboard();

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool CloseClipboard();

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GlobalLock(IntPtr hMem);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool GlobalUnlock(IntPtr hMem);

    public const uint CF_PNG = 0x00000089;
    public const uint GMEM_MOVEABLE = 0x0002;
}
"@

# 读取PNG文件字节
$pngPath = "input.png"
$pngBytes = [File]::ReadAllBytes($pngPath)

# 分配可移动内存块
$hGlobal = [ClipboardHelper]::GlobalAlloc([ClipboardHelper]::GMEM_MOVEABLE, [UIntPtr]$pngBytes.Length)
$pGlobal = [ClipboardHelper]::GlobalLock($hGlobal)

# 将PNG字节复制到内存
[System.Runtime.InteropServices.Marshal]::Copy($pngBytes, 0, $pGlobal, $pngBytes.Length)
[ClipboardHelper]::GlobalUnlock($hGlobal)

# 写入剪贴板
[ClipboardHelper]::OpenClipboard([IntPtr]::Zero)
[ClipboardHelper]::EmptyClipboard()
[ClipboardHelper]::SetClipboardData([ClipboardHelper]::CF_PNG, $hGlobal)
[ClipboardHelper]::CloseClipboard()

Python 原生解决方案

使用ctypes调用Windows API,实现相同逻辑:

import ctypes
from ctypes import wintypes

# 定义Windows API函数
user32 = ctypes.WinDLL('user32', use_last_error=True)
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

CF_PNG = 0x00000089
GMEM_MOVEABLE = 0x0002

user32.OpenClipboard.argtypes = (wintypes.HWND,)
user32.OpenClipboard.restype = wintypes.BOOL

user32.EmptyClipboard.argtypes = ()
user32.EmptyClipboard.restype = wintypes.BOOL

user32.SetClipboardData.argtypes = (wintypes.UINT, wintypes.HGLOBAL)
user32.SetClipboardData.restype = wintypes.HGLOBAL

user32.CloseClipboard.argtypes = ()
user32.CloseClipboard.restype = wintypes.BOOL

kernel32.GlobalAlloc.argtypes = (wintypes.UINT, ctypes.c_size_t)
kernel32.GlobalAlloc.restype = wintypes.HGLOBAL

kernel32.GlobalLock.argtypes = (wintypes.HGLOBAL,)
kernel32.GlobalLock.restype = wintypes.LPVOID

kernel32.GlobalUnlock.argtypes = (wintypes.HGLOBAL,)
kernel32.GlobalUnlock.restype = wintypes.BOOL

def copy_png_to_clipboard(png_path):
    with open(png_path, 'rb') as f:
        png_data = f.read()
    
    # 分配内存
    h_global = kernel32.GlobalAlloc(GMEM_MOVEABLE, len(png_data))
    if not h_global:
        raise ctypes.WinError(ctypes.get_last_error())
    
    try:
        p_global = kernel32.GlobalLock(h_global)
        if not p_global:
            raise ctypes.WinError(ctypes.get_last_error())
        
        # 复制数据到内存
        ctypes.memmove(p_global, png_data, len(png_data))
        kernel32.GlobalUnlock(h_global)
        
        # 写入剪贴板
        if not user32.OpenClipboard(None):
            raise ctypes.WinError(ctypes.get_last_error())
        
        try:
            user32.EmptyClipboard()
            if not user32.SetClipboardData(CF_PNG, h_global):
                raise ctypes.WinError(ctypes.get_last_error())
        finally:
            user32.CloseClipboard()
    except:
        kernel32.GlobalFree(h_global)
        raise

# 使用示例
copy_png_to_clipboard("input.png")

验证方法

将图片复制到支持透明的应用(如Photoshop、Figma、Windows自带的“画图3D”)中,查看背景是否保持透明。

内容的提问来源于stack exchange,提问作者MarcosP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:28:13