What does GDI use biXPelsPerMeter and SetBitmapDimensionEx for?

What does GDI use BITMAP­INFO­HEADER.biXPels­Per­Meter and Set­Bitmap­Dimension­Ex for?


The BITMAP­INFO­HEADER.biXPels­Per­Meter and BITMAP­INFO­HEADER.biYPels­Per­Meter are completely ignored by GDI when loading a bitmap. The values are there for the benefit of image-editing programs who want to record additional information about the bitmap, but GDI ignores them.

Similarly, the Set­Bitmap­Dimension­Ex and Get­Bitmap­Dimension­Ex functions update a SIZE structure associated with each bitmap, but GDI does nothing with the values, aside from initializing them to zero when the bitmap is created.

The value is there so that, for example, a program which puts a bitmap on the clipboard can specify the recommended physical dimensions of the bitmap, in order to help another program that reads the bitmap from the clipboard (for example, a word processor) decide how big to resize the bitmap when it is pasted.

Whether any programs actually do this sort of thing I do not know.

But that's what it's there for, in case anybody wanted to do it.

Comments (16)
  1. Anonymous Coward says:

    Random, most people don't talk about dpi, only graphics experts do. And even then only when resizing the final image for shipping to the printer. Moreover, in Europe (or at least in the DTP circles I've been professionally been in contact with) people and especially graphics artists tend to express fuzziness in pixels/cm.

    And using metric data in the image header makes calculating the dimensions of the image much easier. Most of the world doesn't use inches and other oddities, and additionally a lot of software expects page sizes and such to be specified in some metre-derived quantity.

    And to answer Raymond's question, there are a number of high-profile image manipulators whose names I shall not mention that do use those fields.

  2. JM says:

    @AC: "high-profile image manipulators whose names I shall not mention" sounds like you're talking about members of a pernicious group of celebrity picture falsifiers.

  3. Joshua says:


    Which is the same kind of unit as DPI (both are of fundamental type 1/L).

  4. Anonymous Coward says:

    Joshua, what did you expect? The only sensible options are 1/L and 1/L² and first seems simpler no?

    The only reason to use the second is if you have to express information density of a two-dimensional medium (like a CD or a piece of paper).

  5. >high-profile image manipulators whose names I shall not mention

    It must be Mud-brick Image Store!

  6. Random832 says:

    "Initializing it to a derived value results in false confidence. Better to say "I don't know" when you don't know. Imagine the image gets cropped and resized, and the PelsPerMeter is updated to be 2415."

    I'm not proposing updating PelsPerMeter on resize, I'm proposing updating the thing updated by SetBitmapDimensionEx on resize, or rather not having it exist at all, and having it calculated on-demand by the (manually updated if at all) PelsPerMeter.

    Having three related quantities invites errors. What's the application pasting something supposed to do if PelsPerMeter says one thing and GetBitmapDimensionEx says another?

  7. Random832 says:

    @Anonymous Coward "And to answer Raymond's question, there are a number of high-profile image manipulators whose names I shall not mention that do use those fields."

    What do they do if they don't match? Say, GetBitmapDimensionEx returns 1000×750 (e.g. 100mm x 75mm), the image itself is 640×480, and PelsPerMeter is 3000 (implying 213mm x 160mm)?

    My point was that it's not possible to use both of those fields, so it makes no sense to me that they both exist.

  8. ErikF says:

    The documentation says exactly where the information returned by GetBitmapDimensionEx came from: the SetBitmapDimensionEx function. In other words, Windows doesn't supply the information (your application/someone else does.) If the two sources of information don't match, blame whoever entered those in the first place!

    As to why there are two sources, my guess is that they realized that compatible bitmaps don't have a PelsPerMeter member, so this is the next best thing.

  9. alegr1 says:

    The DPI is very handy, if you want to be able to print a picture with certain dimensions. It's a shame WIA GUI for a scanner ignores the scanner DPI completely, and puts some bogus 72 DPI in the saved image.

  10. Random832 says:

    It's interesting that these values are defined in metric when most people talk about resolution in, well, dpi, to such an extent that "dpi" is the common term. It also seems strange to me that it has a separate size structure (in 0.1-mm units) rather than simply working it out from the pixel dimensions and the *Pels­Per­Meter values. And why does it initialize them to zero instead of initializing them to (e.g.) (width=640)*10000/3780==1693 based on the dimensions of the image?

    MS Paint in Windows 7 appears to initialize *PelsPerMeter to zero, I'm not sure if this has always been the case with earlier versions of MS Paint.

    [Initializing it to a derived value results in false confidence. Better to say "I don't know" when you don't know. Imagine the image gets cropped and resized, and the PelsPerMeter is updated to be 2415. But that number is completely bogus. You then put it in a collage with another image that wasn't resized, and the collage software says, "Oh, I'd better rescale these images so their pelsPerMeter match up", and then you say "Why are my images all being resized randomly?" -Raymond]
  11. Drak says:

    Not entirely sure if it's related, but .Net allows you to set a DPI resolution on a GDI bitmap. If you're pasting one image onto another, and their DPI resolutions are not the same, you get strange size effects. Took me a while to figure out why one specific image was always resizing while all the others I was testing with did not :)

  12. John Doe says:

    @JM, not naming names/companies is a policy in this blog.

    @Random, your question is moot.

    You either start with a BITMAPINFOHEADER to create a HBITMAP, or you already have the HBITMAP (if you prefer, you either start with a HBITMAP to create a BITMAPINFOHEADER, or you already have the BITMAPINFOHEADER). You only have both values when you're marshalling between the two.

    I'd prefer to use HBITMAPs for an in-proc OLE component, but I'd need a serialized BITMAPINFOHEADER if IPC is required (if you prefer, I'd need a serialized BITMAPINFOHEADER through IPC with an out-of-proc OLE wrapper that runs an in-proc OLE component that uses HBITMAPs, so that this OLE component is isolated and it doesn't take my app down with it).

    At most, you should question why aren't both values of the same type. As it stands, the translation isn't symmetric.

  13. Anonymous Coward says:

    Random, examples include setting the pixels/cm setting of documents newly created based on clipboard data and setting the correct size of a raster image pasted into a vector image editor.

  14. Rick Brewster says:

    I tried using these fields to implement a DPI-aware copy-and-paste in Paint.NET.

    As it turns out, no other application set these fields when copying image data to the clipboard. It had no chance of working and I scrapped it.

  15. Joshua says:

    @Rick Brewster: Implement it anyway. It's a very popular dev tool, and when people notice you pass it around in both directions (they probably notice outbound first), you might have a chance of others that know taking it up.

  16. Anonymous Coward says:

    Rick, I don't know what software you're using and because of the policies of this site I will never know, however I do know that software exists that uses and/or sets those fields when using the clipboard to transfer bitmap data.

Comments are closed.

Skip to main content