c# - 检查 Clipboard.GetImage() 在 C# 中是否透明
问题描述
我想我有一个简单的问题,我似乎很难弄清楚 -如何检查我从中获得的图像是否Clipboard.GetImage()
使用透明度。如果是这样,那么我将PictureBox
在透明背景中显示它。
我直接从应用程序复制图片 - 例如浏览器或 Windows 图像查看器之一。将图片粘贴到例如Word将获得透明背景。
我正在使用这段代码:
// Check if the picture in clipboard has any transparency (alpha channel != 255)
Bitmap img = new Bitmap(Clipboard.GetImage());
for (int y = 0; y < img.Height; ++y)
{
for (int x = 0; x < img.Width; ++x)
{
if (img.GetPixel(x, y).A != 255)
{
Debug.WriteLine("Picture is transparent - set breakpoint here");
}
}
}
...
// Show the picture with transparent background - this works fine
img.MakeTransparent(img.GetPixel(0,0));
myPictureBox.Image = (Image)img;
我正在尝试使用网上找到的各种图片,我可以复制/粘贴具有透明背景的图片,所以我知道它们是透明的,但没有图片会触发Debug.WriteLine
并且所有值都等于255
?
虽然我承认之前有人问过这个问题,但我一定做错了什么,因为这个简单的例子不起作用?它们也很旧,所以也许有一种新的更好的方法?除了这些之外,我还试图找到其他解决方案:
.. 还有更多也不是来自 StackOverflow。我见过非常简单的解决方案和可怕的复杂解决方案——但它们似乎都不起作用。
这是因为剪贴板对象看不到透明度还是..?
解决方案
根据@Jeff, CopyTransparentImages的评论,我最终得出了这个解决方案。这将从剪贴板(也将包括 alpha 通道)中获取(真实?)图像,然后我将检查图像是否包含任何透明度。如果是这样,那么根据我的原始问题,我将在将图像背景颜色显示为PictureBox
.
// Get the image formats from clipboard and check if it is transparent
Image imgCopy = GetImageFromClipboard();
bool isClipboardImageTransparent = IsImageTransparent(imgCopy);
if (isClipboardImageTransparent)
{
...
}
// Get the real image from clipboard (this supports the alpha channel)
private Image GetImageFromClipboard()
{
if (Clipboard.GetDataObject() == null) return null;
if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Dib))
{
// Sometimes getting the image data fails and results in a "System.NullReferenceException" error - probably because clipboard handling also can be messy and complex
byte[] dib;
try
{
dib = ((System.IO.MemoryStream)Clipboard.GetData(DataFormats.Dib)).ToArray();
}
catch (Exception ex)
{
return Clipboard.ContainsImage() ? Clipboard.GetImage() : null;
}
var width = BitConverter.ToInt32(dib, 4);
var height = BitConverter.ToInt32(dib, 8);
var bpp = BitConverter.ToInt16(dib, 14);
if (bpp == 32)
{
var gch = GCHandle.Alloc(dib, GCHandleType.Pinned);
Bitmap bmp = null;
try
{
var ptr = new IntPtr((long)gch.AddrOfPinnedObject() + 40);
bmp = new Bitmap(width, height, width * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, ptr);
return new Bitmap(bmp);
}
finally
{
gch.Free();
if (bmp != null) bmp.Dispose();
}
}
}
return Clipboard.ContainsImage() ? Clipboard.GetImage() : null;
}
// Check if the image contains any transparency
private static bool IsImageTransparent(Image image)
{
Bitmap img = new Bitmap(image);
for (int y = 0; y < img.Height; ++y)
{
for (int x = 0; x < img.Width; ++x)
{
if (img.GetPixel(x, y).A != 255)
{
return true;
}
}
}
return false;
}
至少这对我有用:-)
推荐阅读
- flutter - 从 Build->Flutter->Build APK 创建构建可以生成没有颜色和数据的构建
- python - 有没有办法从 Python Tkinter 中特定帧的输入框中检索数据?
- typescript - 打字稿:输入数据
= 结果 - elasticsearch - 异常检测 Kibana 插件的配置
- npm - npm 奇怪的 bug,钛 Appc 合金
- sql-server - 通过 HAproxy 使用 Powershell 连接到 MSSQL
- c++ - 如何将一个范围内的值插入到另一个范围内
- python - 启动使用 py2app 构建的应用程序时出现“ValueError:源代码字符串不能包含空字节”结果
- javascript - Angular:从父组件更新子布尔组件
- apache-kafka - 无法在 kafka 中为批处理模式设置错误处理程序