ホームページ > バックエンド開発 > C++ > さまざまなアプリケーションで透明性のある画像を確実にコピーして貼り付けるにはどうすればよいですか?

さまざまなアプリケーションで透明性のある画像を確実にコピーして貼り付けるにはどうすればよいですか?

Linda Hamilton
リリース: 2025-01-12 14:34:43
オリジナル
255 人が閲覧しました

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

さまざまなアプリケーションで透明な画像を確実にコピーアンドペーストできます

画像をコピーして貼り付けると、異なるプログラム間で透明度が一定に保たれないという問題が発生したことがあるかもしれません。 Chrome では透明度を維持できますが、システム クリップボード オブジェクトを使用して画像を設定すると、透明度が失われる可能性があります。

クリップボードの制限

Windows クリップボードは、画像の透明度をネイティブにサポートしていません。ただし、複数のデータ型を利用して、アプリケーション間の互換性を高めることができます。

PNG ストリーミング: 最適な互換性オプション

PNG ストリーミングは、クリップボード画像の透明性を維持する最も信頼できる方法です。 PNG 画像を GIMP または新しい MS Office プログラムに貼り付けると、透明度が維持されます。

複数のフォーマット、幅広い互換性

より多くのアプリケーションとの互換性を確保するには、PNG、デバイス独立ビットマップ (DIB)、標準ビットマップなど、サポートされている複数の画像形式をクリップボードに含めることをお勧めします。

サンプルコード

<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>
ログイン後にコピー

クリップボードから画像を抽出

クリップボードから画像を抽出するには、サポートされているさまざまな形式を確認する必要があります。最大限の信頼性を確保するために PNG を優先します。

<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>
ログイン後にコピー

(注: 上記のコード スニペットの ImageUtils.GetImageDataImageUtils.CloneImageImageUtils.BuildImage は、実際の状況に応じて自分で実装する必要があります。) これらの関数は画像の処理を担当します。データとビットマップの作成。 この部分の実装は、使用する画像処理ライブラリと特定のプラットフォーム環境によって異なります。

以上がさまざまなアプリケーションで透明性のある画像を確実にコピーして貼り付けるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート