-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Win32 - export bitmap in more clipboard formats #20209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| using var stream = new MemoryStream(); | ||
| bitmap.Save(stream); | ||
|
|
||
| return WriteBytesToHGlobal(ref hGlobal, stream.ToArray().AsSpan()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could probably do here without a copy, there is MemoryStream.GetBuffer(), but it might be larger than you need, so you need to use Length
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thats probably over-optimization. We are rarely copying images that often to have issues with memory copies. Best to be stable in this case.
| biPlanes = 1, | ||
| biBitCount = (ushort)(bitmap.Format?.BitsPerPixel ?? 0), | ||
| biCompression = 0, | ||
| biSizeImage = (uint)(pixelSize.Width * 4 * Math.Abs(pixelSize.Height)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are assuming pixel is 4 bytes here but use any BitsPerPixel value you get from the bitmap. These should be made to match (and match the reality). Some of the formats, and especially the ones with transparency cannot be supported using BITMAPINFOHEADER, you need V5 header. The main benefit of using HBITMAP is that it can support more pixel formats than CF_DIB.
| public static extern int SetDIBits(IntPtr hdc, IntPtr hbm, uint start, uint cLines, IntPtr lpBits, [In] ref BITMAPINFO lpbmi, uint fuColorUse); | ||
|
|
||
| [DllImport("gdi32.dll")] | ||
| public static extern int SetDIBits(IntPtr hdc, IntPtr hbm, uint start, uint cLines, IntPtr lpBits, [In] ref BITMAPINFOHEADER lpbmi, uint fuColorUse); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of [In] ref you can just do in (and pass it without a qualifier at callsite)
| or ClipboardFormatRegistry.BitmapFormat | ||
| or ClipboardFormatRegistry.PngFormatMimeType | ||
| or ClipboardFormatRegistry.JpegFormatMimeType) | ||
| or ClipboardFormatRegistry.PngFormatMimeType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"PNG"?
| private static readonly List<(DataFormat Format, ushort Id)> s_formats = []; | ||
|
|
||
| public static DataFormat PngSystemDataFormat = DataFormat.FromSystemName<Bitmap>("PNG" , AppPrefix); | ||
| public static DataFormat PngDataFormat = DataFormat.FromSystemName<Bitmap>(PngFormatMimeType , AppPrefix); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The names are not too helpful, would prefer PngDataFormat for PNG and PngMimeDataFormat for image/png.
| public const string DibFormat = "CF_DIB"; | ||
| private static readonly List<(DataFormat Format, ushort Id)> s_formats = []; | ||
|
|
||
| public static DataFormat PngSystemDataFormat = DataFormat.FromSystemName<Bitmap>("PNG" , AppPrefix); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is image/png format extracted into const and PNG not?
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
| bitmap.CopyPixels(new PixelRect(pixelSize), (IntPtr)bytes, buffer.Length, stride); | ||
|
|
||
| var infoHeader = new BITMAPINFOHEADER() | ||
| if (!isV5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is not V5 you would need to ensure the bitmap is one of the supported formats
| bV5Height = -pixelSize.Height, | ||
| bV5Planes = 1, | ||
| bV5BitCount = (ushort)bpp, | ||
| bV5Compression = BitmapCompressionMode.BI_BITFIELDS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only valid for 16bpp and 32bpp, must be BI_RGB otherwise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for 555 bitmaps, either provide filter or use BI_RGB
| bV5GreenMask = GetGreenMask(bitmap), | ||
| bV5AlphaMask = GetAlphaMask(bitmap), | ||
| bV5CSType = BitmapColorSpace.LCS_sRGB, | ||
| bV5Intent = BitmapIntent.LCS_GM_BUSINESS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why business here but colorimetric for dib?
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
What does the pull request do?
Adds more image format when bitmaps are exported to clipboard, namely the png and native bitmap(CF_BITMAP) formats, on Windows.
Due to some cleanup, jpeg format is removed from the input preferred formats, i.e. formats we read from the clipboard. This support may be added back later.
What is the current behavior?
We currently export bitmaps using the CF_DIB format. Some apps may not support this format, and thus can't read our bitmaps.
With this PR, our bitmaps are exported in the following formats:
image/png,PNG,CF_DIB,CF_BITMAP, in that order.What is the updated/expected behavior with this PR?
How was the solution implemented (if it's not obvious)?
Checklist
Breaking changes
Obsoletions / Deprecations
Fixed issues
Fixes #20183