Home >Backend Development >C++ >How Can I Reliably Copy and Paste Images with Transparency in Different Applications?

How Can I Reliably Copy and Paste Images with Transparency in Different Applications?

Linda Hamilton
Linda HamiltonOriginal
2025-01-12 14:34:43210browse

How Can I Reliably Copy and Paste Images with Transparency in Different Applications?

Reliable copy-paste of transparent images in different applications

You may have encountered an issue where when you copy and paste an image, the transparency does not remain consistent across different programs. Although Chrome can preserve transparency, it may be lost when an image is set using the system clipboard object.

Clipboard Limitation

The Windows Clipboard does not natively support image transparency. However, you can leverage multiple data types to increase compatibility across applications.

PNG streaming: best compatibility option

PNG streaming is the most reliable way to maintain transparency of clipboard images. Paste the PNG image into GIMP or newer MS Office programs and the transparency will be preserved.

Multiple formats, wider compatibility

To ensure compatibility with more applications, it is recommended to include multiple supported image formats on the clipboard, such as PNG, Device Independent Bitmap (DIB) and standard bitmap.

Sample code

<code class="language-c#">public static void SetClipboardImage(Bitmap image, Bitmap imageNoTr, DataObject data)
{
    Clipboard.Clear();
    if (data == null) data = new DataObject();
    if (imageNoTr == null) imageNoTr = image;

    using (MemoryStream pngMemStream = new MemoryStream())
    using (MemoryStream dibMemStream = new MemoryStream())
    {
        data.SetData(DataFormats.Bitmap, true, imageNoTr); // 设置标准位图(无透明度)
        image.Save(pngMemStream, ImageFormat.Png);
        data.SetData("PNG", false, pngMemStream); // 设置PNG流(GIMP和较新MS Office兼容)
        Byte[] dibData = ConvertToDib(image);
        dibMemStream.Write(dibData, 0, dibData.Length);
        data.SetData(DataFormats.Dib, false, dibMemStream); // 设置DIB格式(处理错误解释透明度的应用)
        Clipboard.SetDataObject(data, true);
    }
}

public static Byte[] ConvertToDib(Image image)
{
    using (Bitmap bm32b = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb))
    {
        using (Graphics gr = Graphics.FromImage(bm32b))
            gr.DrawImage(image, new Rectangle(0, 0, bm32b.Width, bm32b.Height));
        bm32b.RotateFlip(RotateFlipType.Rotate180FlipX);
        Int32 stride;
        Byte[] bm32bData = ImageUtils.GetImageData(bm32b, out stride);
        Int32 hdrSize = 0x28;
        Byte[] fullImage = new Byte[hdrSize + 12 + bm32bData.Length];
        ArrayUtils.WriteIntToByteArray(fullImage, 0x00, 4, true, (UInt32)hdrSize);
        ArrayUtils.WriteIntToByteArray(fullImage, 0x04, 4, true, (UInt32)image.Width);
        ArrayUtils.WriteIntToByteArray(fullImage, 0x08, 4, true, (UInt32)image.Height);
        ArrayUtils.WriteIntToByteArray(fullImage, 0x0C, 2, true, 1);
        ArrayUtils.WriteIntToByteArray(fullImage, 0x0E, 2, true, 32);
        ArrayUtils.WriteIntToByteArray(fullImage, 0x10, 4, true, 3);
        ArrayUtils.WriteIntToByteArray(fullImage, 0x14, 4, true, (UInt32)bm32bData.Length);
        ArrayUtils.WriteIntToByteArray(fullImage, hdrSize + 0, 4, true, 0x00FF0000);
        ArrayUtils.WriteIntToByteArray(fullImage, hdrSize + 4, 4, true, 0x0000FF00);
        ArrayUtils.WriteIntToByteArray(fullImage, hdrSize + 8, 4, true, 0x000000FF);
        Array.Copy(bm32bData, 0, fullImage, hdrSize + 12, bm32bData.Length);
        return fullImage;
    }
}</code>

Extract image from clipboard

To extract an image from the clipboard, you need to check the various supported formats, preferring PNG to ensure maximum reliability:

<code class="language-c#">public static Bitmap GetClipboardImage(DataObject retrievedData)
{
    if (retrievedData.GetDataPresent("PNG", false))
    {
        MemoryStream png_stream = retrievedData.GetData("PNG", false) as MemoryStream;
        if (png_stream != null)
            using (Bitmap bm = new Bitmap(png_stream))
                return ImageUtils.CloneImage(bm);
    }
    else if (retrievedData.GetDataPresent(DataFormats.Dib, false))
    {
        MemoryStream dib = retrievedData.GetData(DataFormats.Dib, false) as MemoryStream;
        if (dib != null)
            return ImageFromClipboardDib(dib.ToArray());
    }
    else if (retrievedData.GetDataPresent(DataFormats.Bitmap))
        return new Bitmap(retrievedData.GetData(DataFormats.Bitmap) as Image);
    else if (retrievedData.GetDataPresent(typeof(Image)))
        return new Bitmap(retrievedData.GetData(typeof(Image)) as Image);
    return null;
}

public static Bitmap ImageFromClipboardDib(Byte[] dibBytes)
{
    if (dibBytes == null || dibBytes.Length < 4 || dibBytes.Length < (Int32)ArrayUtils.ReadIntFromByteArray(dibBytes, 0, 4, true))
        return null;
    Int32 width = (Int32)ArrayUtils.ReadIntFromByteArray(dibBytes, 0x04, 4, true);
    Int32 height = (Int32)ArrayUtils.ReadIntFromByteArray(dibBytes, 0x08, 4, true);
    Int16 planes = (Int16)ArrayUtils.ReadIntFromByteArray(dibBytes, 0x0C, 2, true);
    Int16 bitCount = (Int16)ArrayUtils.ReadIntFromByteArray(dibBytes, 0x0E, 2, true);
    Int32 compression = (Int32)ArrayUtils.ReadIntFromByteArray(dibBytes, 0x10, 4, true);
    if (planes != 1 || (compression != 0 && compression != 3))
        return null;
    PixelFormat fmt;
    switch (bitCount)
    {
        case 32: fmt = PixelFormat.Format32bppRgb; break;
        case 24: fmt = PixelFormat.Format24bppRgb; break;
        case 16: fmt = PixelFormat.Format16bppRgb555; break;
        default: return null;
    }
    Int32 stride = (((((bitCount * width) + 7) / 8) + 3) / 4) * 4;
    Int32 imageIndex = 40 + (compression == 3 ? 12 : 0);
    if (dibBytes.Length < imageIndex) return null;
    Byte[] image = new Byte[dibBytes.Length - imageIndex];
    Array.Copy(dibBytes, imageIndex, image, 0, image.Length);
    Bitmap bitmap = ImageUtils.BuildImage(image, width, height, stride, fmt, null, null);

    // ... (ImageFromClipboardDib function continues,  requires ImageUtils.BuildImage implementation) ...
}</code>

(Note: ImageUtils.GetImageData, ImageUtils.CloneImage and ImageUtils.BuildImage in the above code snippet need to be implemented by yourself according to the actual situation.) These functions are responsible for the processing of image data and the creation of bitmaps. The implementation of this part depends on the image processing library you use and the specific platform environment.

The above is the detailed content of How Can I Reliably Copy and Paste Images with Transparency in Different Applications?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn