我的应用程序应该能够将32位图像(RGB alpha通道)复制到剪贴板,并从剪贴板中粘贴这些图像.为此,我打算使用CF_DIBV5,因为BITMAPV5HEADER结构具有字段bV5AlphaMask.

问题是对于剪贴板中应该如何存储图像数据似乎没有一致意见.在进行一些测试时,我发现应用程序之间有一些差异,使得它不可能得到一般的解决方案.

这是我的观察:

>当我将alpha通道图像从Word 2010或XnView复制到剪贴板时,它将被存储而不会产生不同的像素数据.
>然而,当我使用Firefox或Chrome复制图像时,像素数据似乎被alpha通道预先使用.
> Firefox将bV5AlphaMask设置为0xff000000,而大多数其他应用程序根本不设置它,但保持为0.这是奇怪的,因为这些应用程序将DIB放在实际包含最高8位的alpha通道的剪贴板上,但仍然将bV5AlphaMask设置为0所以人们必须假设如果位深度为32,即使bV5AlphaMask为0,也有一个alpha通道.

为了缩短长篇小说,我的基本问题是:有关Alpha通道数据应如何存储在剪贴板上的官方信息?我特别感兴趣的是找出数据是否必须预付.如上所述,Word 2010和XnView不会超前,而Firefox和Chrome.但是,知道颜色通道是否应该预乘,这一点至关重要.

非常感谢您的光临!

更新2
粘贴到Paint.NET工作正常.这是由于我的代码中的一个错误,如果Alpha通道为0,则没有将颜色通道设置为0,即在这种情况下,预处理未正确完成,这似乎使Paint.NET变得混乱.

仍然未解决的是Internet Explorer 10的问题.当将Alpha通道的PNG复制到剪贴板时,IE 10只是在剪贴板上放置一个24位CF_DIBV5,但是Paint.NET可以使用Alpha通道粘贴此位图,因此必须有另一种格式IE 10暴露于剪贴板.也许它暴露了一个PNG使用CFSTR_FILECONTENTS和CFSTR_FILEDESCRIPTOR.

UPDATE
我现在已经按照下面的arx描述的方式实现了它,它的工作原理很好.但是,仍然有两件让我困惑的事情:

1)将Alpha应用程序中的Alpha通道图像粘贴到Paint.NET中不会保留Alpha通道.图像在Paint.NET中显示为不透明.然而,从Firefox和Chrome粘贴到Paint.NET中,Alpha通道保留完好!我已经倾销了完整的DIBV5,它与我的应用程序是一样的,但仍然可以与FF和Chrome一起使用,但不适用于我的应用程序,所以还必须有其他的东西! Firefox和Chrome必须做一些我的应用程序不做的事情!

2)Internet Explorer 10也是如此.将IE 10的Alpha通道图像粘贴到我的应用程序上根本不起作用…我正在获得一个深度为24的DIB,即没有alpha通道所有.然而,从IE 10粘贴到Paint.NET时,Alpha通道就在那里!所以在这里还要有更多的东西…

我确定有一个正确的方法来存储CF_DIBV5中的alpha,但它并不重要.应用程序已经处理它不一致,所以如果你希望你的应用程序与他人很好地玩,你不能使用CF_DIBV5.

我曾经研究过复制和粘贴透明位图.我的目标是将透明位图成功粘贴到Office和GIMP的两个版本中.我看了几种可能的格式:

CF_BITMAP

透明度总是被忽略.

CF_DIB

以通常的0xAARRGGBB格式使用32bpp BI_RGB. GIMP支持这一点,但没有其他的.

CF_DIBV5

GIMP不支持这一点.

“PNG”

支持的粘贴:GIMP,Word 2000,Excel 2000,Excel 2007和PowerPoint 2007.
粘贴不受支持:Word 2007和OneNote 2007.

如果您复制位图,所有这些应用程序成功导出“PNG”.

但是,Word和OneNote 2007将粘贴从Explorer复制的PNG文件.所以我想出了以下几点:

复制解决方案

将您的透明位图转换为PNG格式.

广告以下剪贴板格式:

“PNG” – 原始的PNG数据.
CF_DIB – 用于不处理透明度的应用程序(如paint).
CFSTR_FILEDESCRIPTOR – 使PNG看起来像一个文件.文件描述符应该有一个发明的文件名,带有“.png”扩展名.
CFSTR_FILECONTENTS – 内容必须作为IStream公开;只是使用HGLOBAL似乎不起作用.数据与“PNG”数据相同.

完成此操作后,我可以将透明位图成功粘贴到GIMP,Office 2000和Office 2007中.也可以将PNG直接粘贴到资源管理器文件夹中.

更新

我意识到我只回答了一半的问题.这是非常好的复制,但如果您想从仅复制CF_DIBV5(如Firefox)的应用程序粘贴,则无法使用.

我建议您使用“PNG”,如果可用,否则回到CF_DIBV5,将其视为预购.这将正确处理Word 2010(导出“PNG”),Firefox和Chrome. XnView只导出不相乘的CF_DIBV5,所以这将无法正常工作.我不确定你能做得更好.

lscf – 用于探索剪贴板格式的工具

这是显示可用剪贴板格式列表的工具的来源.它也可以写一个文件.我叫它lscf.在Visual Studio中创建一个win32控制台应用程序,并通过主函数粘贴此源代码.它有一个非常小的错误:如果您输入格式名称时,它不会显示“未知格式”错误.

#include <Windows.h>

#include <stdio.h>
#include <tchar.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

LPCTSTR cfNames[] = {
    _T("CF_TEXT"),_T("CF_BITMAP"),_T("CF_MetaFILEPICT"),_T("CF_SYLK"),_T("CF_DIF"),_T("CF_TIFF"),_T("CF_OEMTEXT"),_T("CF_DIB"),_T("CF_PALETTE"),_T("CF_PENDATA"),_T("CF_RIFF"),_T("CF_WAVE"),_T("CF_UNICODETEXT"),_T("CF_ENHMetaFILE"),_T("CF_HDROP"),_T("CF_LOCALE"),_T("CF_DIBV5")
};

int Lookupformat(LPCTSTR name)
{
    for (int i = 0; i != ARRAY_SIZE(cfNames); ++i)
    {
        if (_tcscmp(cfNames[i],name) == 0)
            return i + 1;
    }

    return RegisterClipboardFormat(name);
}

void PrintFormatName(int format)
{
    if (!format)
        return;

    if ((format > 0) && (format <= ARRAY_SIZE(cfNames)))
    {
        _tprintf(_T("%s\n"),cfNames[format - 1]);
    }
    else
    {
        TCHAR buffer[100];

        if (GetClipboardFormatName(format,buffer,ARRAY_SIZE(buffer)))
            _tprintf(_T("%s\n"),buffer);
        else
            _tprintf(_T("#%i\n"),format);
    }
}

void WriteFormats()
{
    int count = 0;
    int format = 0;
    do
    {
        format = EnumClipboardFormats(format);
        if (format)
        {
            ++count;
            PrintFormatName(format);
        }
    }
    while (format != 0);

    if (!count)
        _tprintf(_T("Clipboard is empty!\n"));
}

void SaveFormat(int format,LPCTSTR filename)
{
    HGLOBAL hData = (HGLOBAL)GetClipboardData(format);

    LPVOID data = GlobalLock(hData);

    HANDLE hFile = CreateFile(filename,GENERIC_WRITE,CREATE_ALWAYS,0);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        DWORD bytesWritten;
        WriteFile(hFile,data,GlobalSize(hData),&bytesWritten,0);
        CloseHandle(hFile);
    }

    GlobalUnlock(hData);
}

int _tmain(int argc,_TCHAR* argv[])
{
    if (!OpenClipboard(0))
    {
        _tprintf(_T("Cannot open clipboard\n"));
        return 1;
    }

    if (argc == 1)
    {
        WriteFormats();
    }
    else if (argc == 3)
    {
        int format = Lookupformat(argv[1]);
        if (format == 0)
        {
            _tprintf(_T("UnkNown format\n"));
            return 1;
        }

        SaveFormat(format,argv[2]);
    }
    else
    {
        _tprintf(_T("lscf\n"));
        _tprintf(_T("List available clipboard formats\n\n"));
        _tprintf(_T("lscf CF_NAME filename\n"));
        _tprintf(_T("Write format CF_NAME to file filename\n\n"));
    }

    CloseClipboard();

    return 0;
}

Win32剪贴板和Alpha通道图像的更多相关文章

  1. 浅谈移动端网页图片预加载方案

    这篇文章主要介绍了浅谈移动端网页图片预加载方案 的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. ios – 如何通过编程方式为UIButtons组设置单个背景图像

    解决方法要使用选择器数组以编程方式创建按钮,您可以使用以下代码片段://定义策略

  3. iOS启动图像文件类型

    我正在开发一个iPad应用并阅读thispage表示发布图像必须是PNG格式,但在他们的iOS人工指南中,/uploads/20230807/dfd8683904f6d24601aef1a1128c8fa9.png,而不是“必须”.我想使用.jpg格式作为我的发布图像,因为我在.png中的发布图像大小仅为2mb,而.jpg格式只有90kb.谢谢解决方法您需要在Info.plist中指定UILaunhImageFile字段设置此信息将使系统查找Default.jpg及其所有变体而不是.png例如,我正在编写

  4. ios – 删除自定义标签栏上的行

    我制作了一个自定义标签栏,其中一个延伸到栏外.有一条线与中心标签栏重叠.无论如何我可以摆脱这个或隐藏吗?要做到这一点,我只需设置标签栏图像:知道如何隐藏线路吗?谢谢解决方法如果我正确理解你的问题,问题是坐标栏顶部的1-2英寸像素阴影.如果是这种情况,您可以像导航栏一样删除阴影.只需启用剪辑即可.

  5. ios – 无法编辑屏幕截图,performChanges阻止失败

    我正在开发一个允许用户使用PhotoKit编辑照片的应用程序.我之前将编辑过的照片以JPEG格式保存到磁盘.我想避免转换为JPEG,并已实施修改,以便这样做.它适用于使用相机拍摄的照片,但如果您尝试编辑屏幕截图,PHPhotoLibrary.sharedPhotoLibrary().performChanges块将失败并记录操作无法完成.(可可错误-1.).我不确定为什么这会导致performCh

  6. ios – UIBarButtonItem更改播放/暂停按钮的图像

    如果我们两个人为什么不工作感到困惑,我认为这是Swift2/Xcode7beta的变化这样做:希望有所帮助!

  7. ios – 使用UIPasteBoard复制图像(Swift)

    我最近看到了这个项目,用户可以从自定义键盘上点击GIF,他们会看到一个“复制”的工具包.我有一个问题:>如何在产品GIF-Tutorial中重现此工具提示?任何人都可以给我一些示例代码来使用.我理解如何使用UIPasteboard及其功能,但是当我在这个函数中输入UTI类型“public.png”时,我似乎无法使它工作:解决方法尝试使用此代码:你可以找到这个如何工作here!希望这可以帮助

  8. ios – 一个项目中不同目标的不同Default.png文件

    我正在尝试在我的项目中设置第二个目标,但是当我将Default*.png文件拖动到目标的LaunchImages部分时,它会告诉我要从我的原始目标覆盖Default.png.我们如何为不同的目标添加不同的启动图像?在您回答之前,请谅解我不是在寻找如何将不同的一般文件或图像包含在不同的目标.我明白,当我将它们拖到目标窗格的“启动映像”部分时,我正在处理关于Default.png启动映像的问题.解决方法在每个项目的info.plist中,您将创建一个指向启动映像的UILaunchImageFile项.

  9. ios – libpng错误:CgBI:未处理的关键块xcode 7.3

    切换到Xcode7.3,并在同一个项目上运行项目后,我得到以下错误–我已将项目目标的构建设置中的压缩PNG文件设置为NO.我清理并重建了项目,但仍然没有工作,并给出了上述错误.欢迎提出任何解决上述问题的建议/帮助.提前致谢.解决方法除了在项目目标的构建设置中关闭压缩PNG文件标志.我还关闭了另一个标志,即从PNG文件中删除纹理元数据.这样做,解决了问题libpng错误:CgBI:Xcode7.3中

  10. ios – 将许多图像添加到xcodes资产目录 – 如何管理命名以及每个1x,2x,3x?

    我有一个应用程序,我想在xcode的资产目录中添加许多图像.添加1x图像很简单,我只需要拖动第一个文件夹.然而,要添加2x和3x图像,我似乎需要手动拖动每个图像,我宁愿不这样做.每个图像的3种不同尺寸都是相同的,只有不同的尺寸.反正有自动化这个过程吗?

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部