diff --git a/PInvoke/Gdi32/WinGdi.BITMAPINFO.cs b/PInvoke/Gdi32/WinGdi.BITMAPINFO.cs index fc5ca5f9..502ccd7c 100644 --- a/PInvoke/Gdi32/WinGdi.BITMAPINFO.cs +++ b/PInvoke/Gdi32/WinGdi.BITMAPINFO.cs @@ -14,19 +14,20 @@ namespace Vanara.PInvoke BI_RGB = 0, /// - /// A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format is a 2-byte format consisting of a count byte followed by a byte - /// containing a color index. + /// A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format is a 2-byte format consisting of a count + /// byte followed by a byte containing a color index. /// BI_RLE8 = 1, /// - /// An RLE format for bitmaps with 4 bpp. The compression format is a 2-byte format consisting of a count byte followed by two word-length color indexes. + /// An RLE format for bitmaps with 4 bpp. The compression format is a 2-byte format consisting of a count byte followed by two + /// word-length color indexes. /// BI_RLE4 = 2, /// - /// Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks that specify the red, green, and blue - /// components, respectively, of each pixel. This is valid when used with 16- and 32-bpp bitmaps. + /// Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks that specify the + /// red, green, and blue components, respectively, of each pixel. This is valid when used with 16- and 32-bpp bitmaps. /// BI_BITFIELDS = 3, @@ -44,38 +45,50 @@ namespace Vanara.PInvoke { /// The bitmap type. This member must be zero. public int bmType; + /// The width, in pixels, of the bitmap. The width must be greater than zero. public int bmWidth; + /// The height, in pixels, of the bitmap. The height must be greater than zero. public int bmHeight; + /// - /// The number of bytes in each scan line. This value must be divisible by 2, because the system assumes that the bit values of a bitmap form an - /// array that is word aligned. + /// The number of bytes in each scan line. This value must be divisible by 2, because the system assumes that the bit values of + /// a bitmap form an array that is word aligned. /// public int bmWidthBytes; + /// The count of color planes. public ushort bmPlanes; + /// The number of bits required to indicate the color of a pixel. public ushort bmBitsPixel; + /// - /// A pointer to the location of the bit values for the bitmap. The bmBits member must be a pointer to an array of character (1-byte) values. + /// A pointer to the location of the bit values for the bitmap. The bmBits member must be a pointer to an array of character + /// (1-byte) values. /// public IntPtr bmBits; } /// The BITMAPINFO structure defines the dimensions and color information for a DIB. /// - /// A DIB consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the - /// pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeros to end on a LONG data-type boundary. If - /// the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If the height is negative, the bitmap is - /// a top-down DIB and its origin is the upper left corner. + /// A DIB consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of + /// bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeros + /// to end on a LONG data-type boundary. If the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is + /// the lower-left corner. If the height is negative, the bitmap is a top-down DIB and its origin is the upper left corner. /// - /// A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single pointer. For packed - /// bitmaps, the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so that the DIB bitmap array starts on a DWORD boundary. + /// A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single + /// pointer. For packed bitmaps, the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so that the + /// DIB bitmap array starts on a DWORD boundary. /// /// Note - /// The bmiColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to another application. - /// Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values. + /// + /// The bmiColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to another application. + /// + /// + /// Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values. + /// /// [StructLayout(LayoutKind.Sequential)] [PInvokeData("Wingdi.h", MSDNShortId = "dd183375")] @@ -92,13 +105,16 @@ namespace Vanara.PInvoke /// /// /// - /// An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of bmiColors is allowed for - /// functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, they must also call the following bitmap + /// An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of + /// bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, + /// they must also call the following bitmap /// functions: CreateDIBitmap, CreateDIBPatternBrush, CreateDIBSection (The iUsage parameter of CreateDIBSection must be set to DIB_PAL_COLORS.) /// /// /// - /// The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure. + /// + /// The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure. + /// /// The colors in the bmiColors table appear in order of importance. For more information, see the Remarks section. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] @@ -113,6 +129,15 @@ namespace Vanara.PInvoke { bmiHeader = new BITMAPINFOHEADER(width, height, bitCount); } + + /// Creates a structure from the information in a bitmap handle. + /// The handle to a bitmap. + /// + /// A structure with all the information the bitmap handle. If the specified bitmap is less than 24bpp, this resulting structure + /// must not be used without creating unmanaged memory to hold the structure and BITMAPINFO.bmiHeader.biClrUsed * + /// sizeof(RGBQUAD) extra bytes. + /// + public static BITMAPINFO FromHBITMAP(in HBITMAP hBmp) => new BITMAPINFO { bmiHeader = BITMAPINFOHEADER.FromHBITMAP(hBmp) }; } /// The BITMAPINFOHEADER structure contains information about the dimensions and color format of a DIB. @@ -124,16 +149,21 @@ namespace Vanara.PInvoke public int biSize; /// - /// The width of the bitmap, in pixels. If biCompression is BI_JPEG or BI_PNG, the biWidth member specifies the width of the decompressed JPEG or PNG - /// image file, respectively. + /// The width of the bitmap, in pixels. If biCompression is BI_JPEG or BI_PNG, the biWidth member specifies the width of the + /// decompressed JPEG or PNG image file, respectively. /// public int biWidth; /// - /// The height of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight - /// is negative, the bitmap is a top-down DIB and its origin is the upper-left corner. - /// If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS. Top-down DIBs cannot be compressed. - /// If biCompression is BI_JPEG or BI_PNG, the biHeight member specifies the height of the decompressed JPEG or PNG image file, respectively. + /// The height of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left + /// corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner. + /// + /// If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS. Top-down DIBs + /// cannot be compressed. + /// + /// + /// If biCompression is BI_JPEG or BI_PNG, the biHeight member specifies the height of the decompressed JPEG or PNG image file, respectively. + /// /// public int biHeight; @@ -141,8 +171,8 @@ namespace Vanara.PInvoke public ushort biPlanes; /// - /// The number of bits-per-pixel. The biBitCount member of the BITMAPINFOHEADER structure determines the number of bits that define each pixel and - /// the maximum number of colors in the bitmap. This member must be one of the following values. + /// The number of bits-per-pixel. The biBitCount member of the BITMAPINFOHEADER structure determines the number of bits that + /// define each pixel and the maximum number of colors in the bitmap. This member must be one of the following values. /// /// /// Value @@ -155,66 +185,72 @@ namespace Vanara.PInvoke /// /// 1 /// - /// The bitmap is monochrome, and the bmiColors member of BITMAPINFO contains two entries. Each bit in the bitmap array represents a pixel. If the - /// bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table; if the bit is set, the pixel has the color of the - /// second entry in the table. + /// The bitmap is monochrome, and the bmiColors member of BITMAPINFO contains two entries. Each bit in the bitmap array + /// represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table; if + /// the bit is set, the pixel has the color of the second entry in the table. /// /// /// /// 4 /// - /// The bitmap has a maximum of 16 colors, and the bmiColors member of BITMAPINFO contains up to 16 entries. Each pixel in the bitmap is represented - /// by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel - /// contains the color in the second table entry, and the second pixel contains the color in the sixteenth table entry. + /// The bitmap has a maximum of 16 colors, and the bmiColors member of BITMAPINFO contains up to 16 entries. Each pixel in the + /// bitmap is represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte + /// represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color + /// in the sixteenth table entry. /// /// /// /// 8 /// - /// The bitmap has a maximum of 256 colors, and the bmiColors member of BITMAPINFO contains up to 256 entries. In this case, each byte in the array - /// represents a single pixel. + /// The bitmap has a maximum of 256 colors, and the bmiColors member of BITMAPINFO contains up to 256 entries. In this case, + /// each byte in the array represents a single pixel. /// /// /// /// 16 /// - /// The bitmap has a maximum of 2^16 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is - /// NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of red, green, and blue are represented with five bits - /// for each color component. The value for blue is in the least significant five bits, followed by five bits each for green and red. The most - /// significant bit is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must contain the number - /// of entries specified by the biClrUsed member of the BITMAPINFOHEADER. + /// The bitmap has a maximum of 2^16 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member + /// of BITMAPINFO is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of red, green, and + /// blue are represented with five bits for each color component. The value for blue is in the least significant five bits, + /// followed by five bits each for green and red. The most significant bit is not used. The bmiColors color table is used for + /// optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed member of + /// the BITMAPINFOHEADER. /// - /// If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, - /// green, and blue components, respectively, of each pixel. Each WORD in the bitmap array represents a single pixel. + /// If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks + /// that specify the red, green, and blue components, respectively, of each pixel. Each WORD in the bitmap array represents a + /// single pixel. /// /// - /// When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the bits of another mask. - /// All the bits in the pixel do not have to be used. + /// When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the + /// bits of another mask. All the bits in the pixel do not have to be used. /// /// /// /// /// 24 /// - /// The bitmap has a maximum of 2^24 colors, and the bmiColors member of BITMAPINFO is NULL. Each 3-byte triplet in the bitmap array represents the - /// relative intensities of blue, green, and red, respectively, for a pixel. The bmiColors color table is used for optimizing colors used on - /// palette-based devices, and must contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER. + /// The bitmap has a maximum of 2^24 colors, and the bmiColors member of BITMAPINFO is NULL. Each 3-byte triplet in the bitmap + /// array represents the relative intensities of blue, green, and red, respectively, for a pixel. The bmiColors color table is + /// used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed + /// member of the BITMAPINFOHEADER. /// /// /// /// 32 /// - /// The bitmap has a maximum of 2^32 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is - /// NULL. Each DWORD in the bitmap array represents the relative intensities of blue, green, and red for a pixel. The value for blue is in the least - /// significant 8 bits, followed by 8 bits each for green and red. The high byte in each DWORD is not used. The bmiColors color table is used for - /// optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER. + /// The bitmap has a maximum of 2^32 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member + /// of BITMAPINFO is NULL. Each DWORD in the bitmap array represents the relative intensities of blue, green, and red for a + /// pixel. The value for blue is in the least significant 8 bits, followed by 8 bits each for green and red. The high byte in + /// each DWORD is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must + /// contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER. /// - /// If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, - /// green, and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel. + /// If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks + /// that specify the red, green, and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents a + /// single pixel. /// /// - /// When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the bits of another mask. - /// All the bits in the pixel do not need to be used. + /// When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the + /// bits of another mask. All the bits in the pixel do not need to be used. /// /// /// @@ -226,14 +262,14 @@ namespace Vanara.PInvoke public BitmapCompressionMode biCompression; /// - /// The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps. If biCompression is BI_JPEG or BI_PNG, biSizeImage indicates the - /// size of the JPEG or PNG image buffer, respectively. + /// The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps. If biCompression is BI_JPEG or BI_PNG, + /// biSizeImage indicates the size of the JPEG or PNG image buffer, respectively. /// public uint biSizeImage; /// - /// The horizontal resolution, in pixels-per-meter, of the target device for the bitmap. An application can use this value to select a bitmap from a - /// resource group that best matches the characteristics of the current device. + /// The horizontal resolution, in pixels-per-meter, of the target device for the bitmap. An application can use this value to + /// select a bitmap from a resource group that best matches the characteristics of the current device. /// public int biXPelsPerMeter; @@ -241,21 +277,24 @@ namespace Vanara.PInvoke public int biYPelsPerMeter; /// - /// The number of color indexes in the color table that are actually used by the bitmap. If this value is zero, the bitmap uses the maximum number of - /// colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression. + /// The number of color indexes in the color table that are actually used by the bitmap. If this value is zero, the bitmap uses + /// the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression. /// - /// If biClrUsed is nonzero and the biBitCount member is less than 16, the biClrUsed member specifies the actual number of colors the graphics engine - /// or device driver accesses. If biBitCount is 16 or greater, the biClrUsed member specifies the size of the color table used to optimize - /// performance of the system color palettes. If biBitCount equals 16 or 32, the optimal color palette starts immediately following the three DWORD masks. + /// If biClrUsed is nonzero and the biBitCount member is less than 16, the biClrUsed member specifies the actual number of + /// colors the graphics engine or device driver accesses. If biBitCount is 16 or greater, the biClrUsed member specifies the + /// size of the color table used to optimize performance of the system color palettes. If biBitCount equals 16 or 32, the + /// optimal color palette starts immediately following the three DWORD masks. /// /// - /// When the bitmap array immediately follows the BITMAPINFO structure, it is a packed bitmap. Packed bitmaps are referenced by a single pointer. - /// Packed bitmaps require that the biClrUsed member must be either zero or the actual size of the color table. + /// When the bitmap array immediately follows the BITMAPINFO structure, it is a packed bitmap. Packed bitmaps are referenced by + /// a single pointer. Packed bitmaps require that the biClrUsed member must be either zero or the actual size of the color table. /// /// public uint biClrUsed; - /// The number of color indexes that are required for displaying the bitmap. If this value is zero, all colors are required. + /// + /// The number of color indexes that are required for displaying the bitmap. If this value is zero, all colors are required. + /// public uint biClrImportant; /// Initializes a new instance of the structure. @@ -273,47 +312,105 @@ namespace Vanara.PInvoke biCompression = BitmapCompressionMode.BI_RGB; biSizeImage = 0; // (uint)width * (uint)height * bitCount / 8; } + + /// Creates a structure from the information in a bitmap handle. + /// The handle to a bitmap. + /// + /// A structure with all the information the bitmap handle. If the specified bitmap is less than 24bpp, the value is set to the + /// number of structures that must be allocated. + /// + public static BITMAPINFOHEADER FromHBITMAP(in HBITMAP hBmp) + { + // Retrieve the bitmap color format, width, and height. + var bmp = GetObject(hBmp); + + // Convert the color format to a count of bits. + var cClrBits = (ushort)(bmp.bmPlanes * bmp.bmBitsPixel) switch + { + 1 => 1, + <= 4 => 4, + <= 8 => 8, + <= 16 => 16, + <= 24 => 24, + _ => 32, + }; + + // Initialize the fields in the BITMAPINFO structure. + return new BITMAPINFOHEADER + { + biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER)), + biWidth = bmp.bmWidth, + biHeight = bmp.bmHeight, + biPlanes = bmp.bmPlanes, + biBitCount = bmp.bmBitsPixel, + // This value is correct, but there is no memory alllocated to hold these bits + biClrUsed = cClrBits < 24 ? 1U << cClrBits : 0, + // If the bitmap is not compressed, set the BI_RGB flag. + biCompression = BitmapCompressionMode.BI_RGB, + // Compute the number of bytes in the array of color indices and store the result in biSizeImage. The width must be uint + // aligned unless the bitmap is RLE compressed. + biSizeImage = (uint)(((bmp.bmWidth * cClrBits + 31) & ~31) / 8 * bmp.bmHeight), + // Set biClrImportant to 0, indicating that all of the device colors are important. + biClrImportant = 0 + }; + } + + /// Gets the default value for this structure with size fields set appropriately. + public static readonly BITMAPINFOHEADER Default = new BITMAPINFOHEADER { biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER)) }; } /// - /// The DIBSECTION structure contains information about a DIB created by calling the CreateDIBSection function. A DIBSECTION structure includes - /// information about the bitmap's dimensions, color format, color masks, optional file mapping object, and optional bit values storage offset. An - /// application can obtain a filled-in DIBSECTION structure for a given DIB by calling the GetObject function. + /// The DIBSECTION structure contains information about a DIB created by calling the CreateDIBSection function. A DIBSECTION + /// structure includes information about the bitmap's dimensions, color format, color masks, optional file mapping object, and + /// optional bit values storage offset. An application can obtain a filled-in DIBSECTION structure for a given DIB by calling the + /// GetObject function. /// [StructLayout(LayoutKind.Sequential)] [PInvokeData("Wingdi.h", MSDNShortId = "dd183567")] public struct DIBSECTION { /// - /// A BITMAP data structure that contains information about the DIB: its type, its dimensions, its color capacities, and a pointer to its bit values. + /// A BITMAP data structure that contains information about the DIB: its type, its dimensions, its color capacities, and a + /// pointer to its bit values. /// public BITMAP dsBm; + /// A BITMAPINFOHEADER structure that contains information about the color format of the DIB. public BITMAPINFOHEADER dsBmih; + private uint dsBitField1; private uint dsBitField2; private uint dsBitField3; + /// - /// The DSH sectionContains a handle to the file mapping object that the CreateDIBSection function used to create the DIB. If CreateDIBSection was - /// called with a NULL value for its hSection parameter, causing the system to allocate memory for the bitmap, the dshSection member will be NULL. + /// The DSH sectionContains a handle to the file mapping object that the CreateDIBSection function used to create the DIB. If + /// CreateDIBSection was called with a NULL value for its hSection parameter, causing the system to allocate memory for the + /// bitmap, the dshSection member will be NULL. /// public IntPtr dshSection; + /// - /// The offset to the bitmap's bit values within the file mapping object referenced by dshSection. If dshSection is NULL, the dsOffset value has no meaning. + /// The offset to the bitmap's bit values within the file mapping object referenced by dshSection. If dshSection is NULL, the + /// dsOffset value has no meaning. /// public uint dsOffset; /// - /// Specifies three color masks for the DIB. This field is only valid when the BitCount member of the BITMAPINFOHEADER structure has a value greater - /// than 8. Each color mask indicates the bits that are used to encode one of the three color channels (red, green, and blue). + /// Specifies three color masks for the DIB. This field is only valid when the BitCount member of the BITMAPINFOHEADER structure + /// has a value greater than 8. Each color mask indicates the bits that are used to encode one of the three color channels (red, + /// green, and blue). /// #pragma warning disable IDE1006 // Naming Styles + public uint[] dsBitFields #pragma warning restore IDE1006 // Naming Styles { get => new[] { dsBitField1, dsBitField2, dsBitField3 }; set { dsBitField1 = value[0]; dsBitField2 = value[1]; dsBitField3 = value[2]; } } + + /// Gets the default value for this structure with size fields set appropriately. + public static readonly DIBSECTION Default = new DIBSECTION { dsBmih = BITMAPINFOHEADER.Default }; } /// The RGBQUAD structure describes a color consisting of relative intensities of red, green, and blue. @@ -341,6 +438,10 @@ namespace Vanara.PInvoke set { rgbReserved = value.A; rgbBlue = value.B; rgbGreen = value.G; rgbRed = value.R; } } + /// Gets a value indicating whether any transparency is defined. + /// if this value is transparent; otherwise, . + public bool IsTransparent => rgbReserved == 0; + /// Performs an implicit conversion from to . /// The c. /// The result of the conversion.