Jump to content

PNG format in clipboard


Recommended Posts

My primary graphics tool is Paint.Net, but I have found an inadequacy for what I am doing.

Paint.NET copies data to the clipboard in the following formats

PaintDotNet.MaskedSurface

Format17

System.Drawing.Bitmap

Bitmap

DeviceIndependentBitmap

found by examining data.GetFormats() in C#. I cannot use PaintDotNet.MaskedSurface in my application and the others don't provide full transparency information for PNGs. Is there a way to have Paint.NET copy data to the clipboard using "PNG" format?

In my app, I can copy an image into the clipboard using the following code, and all transparency information is retained.

using (MemoryStream stream = new MemoryStream())

{

_Bitmap.Save(stream, ImageFormat.Png);

var data = new DataObject("PNG", stream);

Clipboard.Clear();

Clipboard.SetDataObject(data, true);

}

and I can read the same from the clipboard using the following

IDataObject data = Clipboard.GetDataObject();

if (data.GetFormats().Contains("PNG")){

MemoryStream ms = (System.IO.MemoryStream)data.GetData("PNG");

_Bitmap = (Bitmap)Bitmap.FromStream(ms, true);

}

Can this be accomplished in Paint.NET, or can an extension be created that will do this?

Thanks in advance...

Link to comment
Share on other sites

The bitmap data (DIB) that Paint.NET copies should be stored in PBGRA format (premultiplied alpha), even though DIB doesn't allow you to specify anything about how the alpha channel is encoded. You simply need to divide each color component by the alpha value. There will be a loss of precision, but it will give you transparency you need.

ColorBgra c = ...; // get color from clipboard bitmap, which is in PBGRA
int newBlue = (c.Blue * 255) / c.Alpha; // this is the regular BGRA value
int newGreen = (c.Green * 255) / c.Alpha; // this is the regular BGRA value
int newRed = (c.Red * 255) / c.Alpha; // this is the regular BGRA value
int newAlpha = c.Alpha;
etc.

You can make this much faster by using a lookup table. That's what Paint.NET does.

I'm hesitant to add yet another format to what Paint.NET copies to the clipboard. This is a very delicate code path, and already has all sorts of problems with out of memory errors.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

The bitmap data (DIB) that Paint.NET copies should be stored in PBGRA format (premultiplied alpha), even though DIB doesn't allow you to specify anything about how the alpha channel is encoded. You simply need to divide each color component by the alpha value. There will be a loss of precision, but it will give you transparency you need.

ColorBgra c = ...; // get color from clipboard bitmap, which is in PBGRA
int newBlue = (c.Blue * 255) / c.Alpha; // this is the regular BGRA value
int newGreen = (c.Green * 255) / c.Alpha; // this is the regular BGRA value
int newRed = (c.Red * 255) / c.Alpha; // this is the regular BGRA value
int newAlpha = c.Alpha;
etc.

You can make this much faster by using a lookup table. That's what Paint.NET does.

I'm hesitant to add yet another format to what Paint.NET copies to the clipboard. This is a very delicate code path, and already has all sorts of problems with out of memory errors.

Thanks Rick, but I was looking for a way to paste an entire image into my application from Paint.NET.

Link to comment
Share on other sites

  • 8 months later...

The bitmap data (DIB) that Paint.NET copies should be stored in PBGRA format (premultiplied alpha), even though DIB doesn't allow you to specify anything about how the alpha channel is encoded. You simply need to divide each color component by the alpha value. There will be a loss of precision, but it will give you transparency you need.

Has this changed since your post? I just did some analysis of Paint.NET 3.5.10 clipboard behavior and I can't get any real alpha data out of Paint.NET except in its proprietary format. Here's what I tried:

1) Create new 256x256 image in Paint.NET

2) Select all, delete

3) Set foreground color to white with alpha of 186 (0xBA)

4) Flood fill

5) Copy entire image to clipboard

6) Paste into my own .NET app

7) Call IDataObject.GetFormats(), IDataObject.GetData() on each format, and inspect the results:

  • "PaintDotNet.MaskedSurface" (MemoryStream, alpha set to 0xBA - clearly visible in the raw data)
  • "Format17" (MemoryStream, alpha set to 0xFF)
  • "Bitmap" (InteropBitmap, alpha set to 0xFF)
  • "System.Drawing.Bitmap" (System.Drawing.Bitmap, did not inspect)
  • "System.Windows.Media.Imaging.BitmapSource" (System.Windows.Media.Imaging.BitmapSource, alpha set to 0xFF)
  • "DeviceIndependentBitmap" (MemoryStream, alpha set to 0xFF)

I've also tested the following:

  • Copy from Word 2010 into my app: alpha is preserved (via "Bitmap" clipboard format)
  • Copy from Word 2010 into Inkscape: alpha is preserved
  • Copy from Paint.NET into Word 2010: alpha is lost (solid white background)
  • Copy from Paint.NET into Inkscape: alpha is lost (solid white background)

So, here are some possible theories:

  1. Paint.NET is only intended to interoperate with itself when it comes to putting real alpha on the clipboard (suggested by my observations)
  2. Paint.NET is supposed to put real alpha data on the clipboard in formats other than its own, but a bug is preventing it from doing so (suggested by your post)
  3. My procedure is flawed (always possible)

Your clarification would be much appreciated.

Edited by ral42
Link to comment
Share on other sites

This thread is from July 2011 and is dead. Please don't necropost (see the rules).

Word probably isn't meant to handle alpha, it's not an image composing application. If Inkscape doesn't handle it, then that's probably an Inkscape bug.

Thread Closed

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...