-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wpf/WinForms: Fix adding transparent images to the clipboard
Ignore Thumbs.db files
- Loading branch information
Showing
8 changed files
with
134 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ Source/Components | |
AppPackages | ||
packages/ | ||
.vs/ | ||
[Tt]humbs.db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
using System; | ||
using System.IO; | ||
using Eto.Drawing; | ||
|
||
namespace Eto | ||
{ | ||
partial class Win32 | ||
{ | ||
public static Bitmap FromDIB(MemoryStream ms) | ||
{ | ||
var header = new byte[40]; | ||
ms.Read(header, 0, header.Length); | ||
var size = BitConverter.ToInt32(header, 0); | ||
var width = BitConverter.ToInt32(header, 4); | ||
var height = BitConverter.ToInt32(header, 8); | ||
var bpp = BitConverter.ToInt16(header, 14); | ||
var compression = BitConverter.ToInt32(header, 16); | ||
if (size > header.Length) | ||
ms.Seek(size - header.Length, SeekOrigin.Current); | ||
|
||
if (bpp != 32) | ||
return null; | ||
if (compression == 3) // BI_BITFIELDS | ||
{ | ||
// three dwords, each specifies the bits each RGB components takes | ||
// we require each takes one byte | ||
var segments = new byte[sizeof(int) * 3]; | ||
ms.Read(segments, 0, segments.Length); | ||
var rcomp = BitConverter.ToInt32(segments, 0); | ||
var gcomp = BitConverter.ToInt32(segments, 4); | ||
var bcomp = BitConverter.ToInt32(segments, 8); | ||
if (rcomp != 0xFF0000 || gcomp != 0xFF00 || bcomp != 0xFF) | ||
return null; | ||
} | ||
else if (compression != 0) // BI_RGB | ||
return null; | ||
|
||
var bmp = new Bitmap(width, height, PixelFormat.Format32bppRgba); | ||
using (var bd = bmp.Lock()) | ||
{ | ||
for (int y = height - 1; y >= 0; y--) | ||
for (int x = 0; x < width; x++) | ||
{ | ||
var b = ms.ReadByte(); | ||
var g = ms.ReadByte(); | ||
var r = ms.ReadByte(); | ||
var a = ms.ReadByte(); | ||
var af = a / 255f; | ||
if (af > 0) | ||
bd.SetPixel(x, y, new Color(r / af, g / af, b / af, af)); | ||
} | ||
} | ||
return bmp; | ||
} | ||
|
||
static void Write(Stream stream, byte[] val) => stream.Write(val, 0, val.Length); | ||
|
||
public static MemoryStream ToDIB(this Bitmap bitmap, int dpi = 96) | ||
{ | ||
using (var bd = bitmap.Lock()) | ||
{ | ||
if (bd.BytesPerPixel == 4 || bd.BytesPerPixel == 3) // only 32bpp or 24bpp supported | ||
{ | ||
var ms = new MemoryStream(bitmap.Width * bitmap.Height * bd.BytesPerPixel + 40); | ||
// write BITMAPINFOHEADER | ||
const float InchesPerMeter = 39.37f; | ||
var pelsPerMeter = Math.Round(dpi * InchesPerMeter); // convert dpi to ppm | ||
Write(ms, BitConverter.GetBytes((uint)40)); // biSize | ||
Write(ms, BitConverter.GetBytes((uint)bitmap.Width)); // biWidth | ||
Write(ms, BitConverter.GetBytes((uint)bitmap.Height));// biHeight | ||
Write(ms, BitConverter.GetBytes((ushort)1)); // biPlanes | ||
Write(ms, BitConverter.GetBytes((ushort)bd.BitsPerPixel)); // biBitCount | ||
Write(ms, BitConverter.GetBytes((uint)0)); // biCompression (BI_RGB, uncompressed) | ||
Write(ms, BitConverter.GetBytes((uint)0)); // biSizeImage | ||
Write(ms, BitConverter.GetBytes((uint)pelsPerMeter)); // biXPelsPerMeter | ||
Write(ms, BitConverter.GetBytes((uint)pelsPerMeter)); // biYPelsPerMeter | ||
Write(ms, BitConverter.GetBytes((uint)0)); // biClrUsed | ||
Write(ms, BitConverter.GetBytes((uint)0)); // biClrImportant | ||
|
||
var hasAlpha = bd.BytesPerPixel == 4; | ||
// write RGB data, dibs are flipped vertically | ||
for (int y = bitmap.Height - 1; y >= 0; y--) | ||
{ | ||
for (int x = 0; x < bitmap.Width; x++) | ||
{ | ||
var p = bd.GetPixel(x, y); | ||
// need to write RGB premultiplied by alpha (and round up) | ||
ms.WriteByte((byte)(p.B * p.A * 255f + .5f)); | ||
ms.WriteByte((byte)(p.G * p.A * 255f + .5f)); | ||
ms.WriteByte((byte)(p.R * p.A * 255f + .5f)); | ||
if (hasAlpha) | ||
ms.WriteByte((byte)p.Ab); | ||
} | ||
} | ||
|
||
ms.Position = 0; | ||
return ms; | ||
} | ||
} | ||
return null; | ||
} | ||
} | ||
} |