2012-06-30 26 views
8

Nota: Esta pregunta se trata de pegar desde el portapapeles, no de copiar en el portapapeles. Hay varias publicaciones sobre cómo copiar en el portapapeles, pero no pude encontrar una que aborde esta pregunta.¿Cómo pegar una imagen transparente desde el portapapeles en una aplicación C# winforms?

¿Cómo puedo pegar una imagen con transparencia, for example this one, en una aplicación de winforms y conservar la transparencia?

He intentado usar System.Windows.Forms.GetImage(), pero eso produce un mapa de bits con un fondo negro.

Copio esta imagen desde Google Chrome, y admite varios formatos de portapapeles, incluidos DeviceIndependentBitmap y Format17.

+0

en realidad, parece Chrome en realidad no poner válida 'Format17' en su portapapeles, ni manag e para pegar 'Format17' cuando lo coloco en el portapapeles programáticamente. – Nyerguds

Respuesta

12

Chrome copia la imagen en el portapapeles en un formato de 24 bpp. Que convierte la transparencia en negro. Puede obtener un formato de 32bpp del portapapeles pero eso requiere manejar el formato DIB. No hay incorporado en el soporte para que, en System.Drawing, se necesita un poco de función auxiliar que hacen que la conversión: el uso

private Image GetImageFromClipboard() { 
     if (Clipboard.GetDataObject() == null) return null; 
     if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Dib)) { 
      var dib = ((System.IO.MemoryStream)Clipboard.GetData(DataFormats.Dib)).ToArray(); 
      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; 
    } 

muestra:

protected override void OnPaint(PaintEventArgs e) { 
     using (var bmp = GetImageFromClipboard()) { 
      if (bmp != null) e.Graphics.DrawImage(bmp, 0, 0); 
     } 
    } 

que produjo esta captura de pantalla con la forma de BackgroundImage propiedad establecida en un mapa de bits de almacén:

enter image description here

+0

Brillante. Muchas gracias siempre. – bright

+2

¡Notado - las imágenes se giran 180 grados! La imagen de arriba también se rota desde el original. ¿Alguna idea de por qué? – bright

+2

Pude solucionar esto con image.RotateFlip (SD.RotateFlipType.Rotate180FlipX). Sin embargo, no sé por qué el código anterior causa la rotación y el volteo. – bright

Cuestiones relacionadas