Page 1 of 2 12 LastLast
Results 1 to 40 of 44

Thread: [VB6] Color Management with GDI+ (updated 20 Sep 14)

  1. #1

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Updates (see post #2 for bug descriptions):
    20 Sep 14
    :: Added patch for a specific case when GdipBitmapLockBits fails to lock image data
    :: Added support for JPGs where GDI+ won't return any ICC information. See posts 9-13
    :: Added support for other 8 bpp images. See posts 14-22
    10 Sep 14: Added support for ICC profiles embedded into the BMP format
    31 Aug 14: Fixed JPG related GDI+ bug

    Higher quality images often have a color management profile (ICM/ICC) embedded into their file. These embedded profiles can be retrieved from GDI+ most times. Not many image formats support embedded profiles, but these do per Color.org: png, tif, jpg & gif. Additionally, per Microsoft, bitmaps can support ICC profiles also.

    When embedded, the image's creator provided it so that it can be used to reproduce the image on any monitor/printer in the colors that the creator intended. By ignoring the profile, what you get is not what the creator intended. Sometimes it can be radically different. Images without ICC profiles are at the mercy of the rendering application. GDI+ does a fair job without embedded profiles, but its hands are tied when best-guessing how to interpret the colors.

    Windows provided color management for quite awhile now, but it is the application's responsibility to apply it. The flat GDI+ API wrapper doesn't support color management directly. But with the use of Windows APIs we can still use GDI+ and apply color management

    For a project that doesn't rely on GDI+ for displaying images with embedded ICC profiles, see Tanner's work here. This project is not meant to be competitive with Tanner's hDC-based solution, it is provided as a workaround for those that exclusively use GDI+ for image rendering/processing, no device contexts used in transformations. I started this about 2 years ago & lost interest. Can rest easier now

    This sample project uses Windows to help transform colors, but the result is maintained and used by GDI+. From the sample screenshot, you can see a radical example along with a real-world example of how color management can improve what is displayed. And this sample project may include the only VB6 code that processes a GIF embedded ICC profile instead of ignoring them. To be fair, embedded GIFs are really hard to find.

    To find other images to play with, google for: color profile test

    From time to time, will update this as needed

    Request. If anyone would like to upload an 8 bit grayscale JPG, TIFF or PNG with the appropriate ICC profile, embedded or not, please do so. I'd like to examine them. Currently, processing 8 bit images other than GIF/BMP is turned off in the code.
    Note: 8 bit image processing turned on with the 20 Sep update

    Note: The included bitmap sample image will not be read by VB's LoadPicture function. Believe VB does not support any bitmap using version 4 or 5 of the BITMAPINFOHEADER. But such images can be loaded via setting a DIB's pixel data to the pixel data contained in the bitmap file.

    How do I load any profile I want and use it in the transformation?
    Open the file and read it ito a byte array, then sample code provided. Project will need to be modified to accept a user-provided profile handle to the pvColorManageImage method.
    Note: In most recent update, modified function to include an optional FileName parameter
    Code:
    hProfile = pvCreateProfile(VarPtr(array(0)), UBound(array)+1)
    ' array can be erased immediately after function returns
    ' CloseColorProfile must be called on the returned profile handle, when no longer needed
    Attached Images Attached Images  
    Attached Files Attached Files
    Last edited by LaVolpe; Sep 20th, 2014 at 07:56 PM. Reason: replaced embedded ICC BMP
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  2. #2

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Bug reports/fixes

    JPEG embedded profiles: GDI+ on Vista & below (not yet tested on Win7+) will not return the entire ICC profile embedded in a JPG if that profile was split among multiple JPG tags. Only the 1st tag data is returned which is just a portion of the entire profile.
    Fix: compare byte count returned by GDI+ with ICC profile size. If missing bytes, go get them by parsing the JPEG file manually
    Follow up: Per Tanner, Win7 returns the entire profile, not just the first tag data. This workaround needed for v1.0 & also dependent on the v1.1 build installed on target machine.

    JPEG embedded profiles: Sometimes GDI+ won't return an embedded profile at all and honestly not sure of the reason why. See post #9 below
    Fix: manually parse out the icc profiles in a JPG as needed

    WMFs: If you modify the code and try to send a loaded WMF to the color management routine, you will likely crash. Not all image formats can be accessed with GdipBitmapLockBits.
    Fix for any image format not supported by GdipBitmapLockBits
    1) Create new GDI+ bitmap: GdipCreateBitmapFromScan0 in 24bpp or 32bpp, sized as needed
    2) Get a device context to draw WMF/image into: GdipGetImageGraphicsContext
    3) Draw image to that context: GdipDrawImageRectRectI & destroy context: GdipDeleteGraphics
    4) Transform those bits retrieved from GdipBitmapLockBits

    BMP/GIF embedded ICC profiles are not recognized by GDI+
    Fix: add custom handling procedures to the sample project to scan those file formats for ICC profiles

    GDI+ v1.0 apparent bug? A specific jpg image (post #9) resulted in GdipBitmapLockBits to fail when reading the pixel data. That same image, in updated GDI+ DLL does not generate the same error.
    Fix: For this project & future ones, if GdipBitmapLockBits fails when reading pixel data, simply call it again. If fails twice, then come up with an alternate solution possibly by rendering the pixels elsewhere & getting the data from there. If GDI+ loaded it, the pixel data should be there

    Note: The sample project could be modified for more efficient processing if used in your projects. Here are a couple of recommendations:

    1) If loading by file name, might be better to modify the custom methods that process JPEG,GIF ICC profile searching when those methods are called. In those methods, the entire file is read into an array & processed. Not truly necessary. Those routines can read chunks/bytes, as needed, directly from a file using Seek (VB6) or ReadFile (API) vs loading potentially large files in their entirety when entire file is needed for this purpose. The bitmap custom routine aborts very quickly as is.

    2) As mentioned in code comments, you can turn off image formats for processing by rem'ing out the appropriate lines of code in the pvIsICCsupported method. Useful if you don't care to process bitmaps and/or gifs, for example.
    Last edited by LaVolpe; Sep 20th, 2014 at 07:58 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Non-RGB Color Spaces

    CMYK: Since GDI+ was first released, it has supported CMYK, but how well is another question.

    v1.0 loading: Will attempt to convert CMYK to RGB internally. GDI+ will not return the original CMYK data. Applying an ICC profile to the image is a waste of time
    v1.0 saving: to be added (testing)

    v1.1 loading: Similar as v1.0 of GDI+, however, this color space is now exposed a bit more. One can get the original CMYK bytes and can apply a color profile to it. GDI+ introduced a new pixel format: PixelFormatCMYK
    v1.1 saving: to be added (testing)

    Note: Some CMYK images may look inverted (color negative) after processed. I've seen this with JPGs that have been extracted from PDF files. It seems that without a specific tag within the PDF image description, the 4 cmyk channels should be first inverted before applying a CMYK profile. Unless you are extracting the PDF images, you'll have no way of knowing this in advance. Code-wise for a fix: requires getting the original cmyk bytes & XOR'ing each with 255. Then applying a good cmyk color profile against those inverted bytes. Not the same result if you XOR the bytes after transformation.

    Sample code (GDI+ v1.0 does not retrieve original cmyk data):
    Code:
    ' Assumptions
    ' lRect is GDI+ RECTL strcutre filled out
    ' tBmpData is GDI+ BitmapData structure & .PixelFormat = PixelFormatCMYK
    ' rgbBmpData also BitmapData structure & .PixelFormat = PixelFormat24bpp
    ' hTransform already created using a source CMYK profile & destination sRGB profile 
    ' hImage is the loaded GDI+ CMYK image handle
    ' CMimage will be the color transformed image handle
    
    Dim bCMYK() As Long, X As Long
    ReDim bCMYK(0 To lRect.Width * lRect.Height - 1)
    tBmpData.Scan0Ptr = VarPtr(bCMYK(0))
    tBmpData.stride = lRect.Width * 4
    If GdipBitmapLockBits(hImage, lRect, ImageLockModeRead Or ImageLockModeUserInputBuf, tBmpData.PixelFormat, tBmpData) = 0 Then
        For X = 0 To UBound(bCMYK)
            bCMYK(X) = bCMYK(X) Xor &HFFFFFFFF ' XOR cmyk bits
        Next
        GdipBitmapUnlockBits hImage, tBmpData   ' done with it, bCMYK() has what we need
        
        If GdipCreateBitmapFromScan0(lRect.Width, lRect.Height, 0&, rgbBmpData.PixelFormat, ByVal 0&, CMimage) = 0& Then
            If Not GdipBitmapLockBits(CMimage, lRect, ImageLockModeRead Or ImageLockModeWrite, rgbBmpData.PixelFormat, rgbBmpData) = 0 Then
                GdipDisposeImage CMimage: CMimage = 0&  ' shouldn't have happened
            Else
                ' now the color transformation can be applied
                lResult = TranslateBitmapBits(hTransform, tBmpData.Scan0Ptr, BM_KYMCQUADS, _
                        tBmpData.Width, tBmpData.Height, tBmpData.stride, _
                        rgbBmpData.Scan0Ptr, BM_RGBTRIPLETS, rgbBmpData.stride, ByVal 0&, 0&)
                GdipBitmapUnlockBits CMimage, rgbBmpData ' save changes
                If lResult = 0 Then
                    GdipDisposeImage CMimage: CMimage = 0& ' conversion failed
                End If
            End If
        End If
    End If
    Sample of such an image that was extracted from the pdf specification. Note that the jpg does NOT have an embedded CMYK profile. Need to use one of yours or one extracted from another cmyk image. The source JPG is also included
    Name:  cmyktests.png
Views: 2686
Size:  70.3 KB
    Attached Files Attached Files
    Last edited by LaVolpe; Aug 31st, 2014 at 04:39 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  4. #4
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    806

    Re: [VB6] Color Management with GDI+

    LaVolpe, thanks much for sharing this code. Many GDI+ users probably aren't familiar with the benefits of LockBits and this is a great example of how it can be used.

    Re: 8bpp non-grayscale paletted images, e.g. GIF or PNG. I've never encountered these in the wild, and seeing as the primary use-case of palette images is reduced file size, not sure you'd find such an image with embedded ICC profile. (At least, not one created by someone who knew what they were doing.)

    Similarly, you'd have to jump through some hoops to handle an image like this, as WCS has no built-in support for palette-based formats. (http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx). Not sure it's worth the trouble to handle this case at all, given these conditions.

    Finally, 32bpp with alpha is definitely a valid case to cover. PNGs coming from 3D modeling software (e.g. Blender) will often include an embedded ICC profile, so worthwhile to handle such images, especially in an alpha image control I think.
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  5. #5

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    Tanner, 32bpp alpha is supported in the project, not pre-multiplied alpha. If I find a need for that, I can support it easily. I've included tips on how it could be supported if anyone wishes to do so.

    Doubt anyone would intentionally premultiply the bits & provide a profile as that would kinda defeat the true purpose of the profile: premultiplied RGB channels cause permanent color change from the original
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  6. #6
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    806

    Re: [VB6] Color Management with GDI+

    Quote Originally Posted by LaVolpe View Post
    Tanner, 32bpp alpha is supported in the project, not pre-multiplied alpha. If I find a need for that, I can support it easily. I've included tips on how it could be supported if anyone wishes to do so.

    If anyone is knowing what they are doing with profiles, doubt anyone would intentionally premultiply the bits & provide a profile as that would kinda defeat the true purpose of the profile: premultiplied RGB channels cause permanent color change from the original
    It's my understanding that when loading images, GDI+ premultiplies all 32bpp data by default. I don't know of a way to override this behavior.

    Additionally, you have to verify the premultiplication programmatically, as the premultiplied alpha IDs are never used on GDI+ v1.0. (Yet another caveat of that version, ugh.)
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  7. #7

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    Quote Originally Posted by Tanner_H View Post
    It's my understanding that when loading images, GDI+ premultiplies all 32bpp data by default. I don't know of a way to override this behavior.

    Additionally, you have to verify the premultiplication programmatically, as the premultiplied alpha IDs are never used on GDI+ v1.0. (Yet another caveat of that version, ugh.)
    1st point: Nope. It is true if you render the image to a GDI 32bit DC. GDI+ premultiplies the rendered pixels. Whether the original image is premultiplied or not, you can request the bits either way, via LockBits, & GDI+ will happily give them to you in either format; doing the conversion if needed. Lockbits will convert between non-paletted formats to non-paletted formats and from paletted formats to non-paletted formats, so no special manual conversion routines needed in those cases. However, not all image formats can make use of LockBits, i.e., WMF

    2nd point. For our purposes, that is true. But TGA for example (and not supported by GDI+) can identify premultiplication in their format. Think there is another format which can do that also, but not coming to mind right off. But ICC embedded capable formats do not include one that allows premultiplied components. This would be an issue and could be addressed if someone were to try to apply color transformation to premultiplied components with a manually loaded profile. But the sample project processes embedded profiles only & can be modified to process user-supplied profiles -- user's responsibility for this sample project. The code I use for other projects will take this into consideration

    Edited: that other format couldn't bring to mind is TIFF. May try to create my own TIFF premultiplied image with embedded ICC and see how other viewers would render it when compared to my methods. Yes, TIFF can be coded as premultiplied via its &H152 tag, value of 1

    FYI: My alpha image control does contain a routine that can determine premultiplication 99.9% of the time & has just 4 rare cases where it is possible it can be fooled
    - Every alpha component is zero; assumes alpha components not used vs 100% transparent
    - Every R,G,B component < alpha component; assumes premultiplied (correct 99.9% of time)
    - Alpha component used for other purposes (i.e., hiding data); any assumption is wrong
    - Bitmaps from a stdPicture object containing alpha components; assumes not used. VB stdPicture (LoadPicture) does not natively support 32bpp - but can be forced to via OleCreatePictureIndirect. Also dirty alpha components possible & proven, i.e., 24bpp image from clipboard can be 32bpp when returned from Clipboard.GetData & non-zero alpha components are found. Also when using stdPicture.Render from a WMF to 32bpp hDC, the alpha channel can be written into inadvertently

    The premultiplication IDs will be used by GDI+ if the image is created in that format via GDI+ calls, i.e., CreateBitmapxxx types of calls. But yes, when loading an image from disc, haven't seen a case yet where GDI+ will make a determination of premultiplied; hence the routine I built for that purpose.
    Last edited by LaVolpe; Sep 1st, 2014 at 01:47 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    Updated project to support embedded/linked profiles contained with bitmap image formats.

    Per MSDN, BITMAPV5HEADER supports ICC profiles.

    FYI: VB's LoadPicture method doesn't seem to support v4 or v5 headers. So a bitmap with a v5 header will be reported as an invalid image format by VB
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  9. #9
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+

    Good code.

    For some files, loading would fail on systems below Win7, with the following message "The image you supplied does not have a valid embedded ICC profile or the profile is the same as this monitor's default profile.". Actually it is not the case, the failure is due to GdipGetPropertyItemSize bug which often may return a zero profile size.

    Attached ZIP below contains an example of such a file, which images before and after the ICC-conversion are shown in a screenshot.

    To work around the above said GdipGetPropertyItemSize bug, one can pass the bytes obtained from, e.g. JPEG APP2 marker, excluding marker (2 bytes). The total bytes so obtained being the profile size. Memo: First 16 bytes in the array should be excluded, like whenever after calling GdipGetPropertyItem.
    .
    Name:  ScreenShot.jpg
Views: 2962
Size:  49.3 KB
    Attached Files Attached Files
    Last edited by Brenker; Sep 13th, 2014 at 01:20 AM. Reason: Add "Memo"

  10. #10

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    Quote Originally Posted by Brenker View Post
    Attached ZIP below contains an example of such a file, which images before and after the ICC-conversion are shown in a screenshot.

    To work around the above said GdipGetPropertyItemSize bug, one can pass the bytes obtained from, e.g. JPEG APP2 marker, excluding marker (2 bytes). The total bytes so obtained being the profile size. Memo: First 16 bytes in the array should be excluded, like whenever after calling GdipGetPropertyItem.
    Interesting. Parsing it does return a valid ICC profile. I'll take a closer look in another day or so. Kinda curious as to why GDI+ doesn't want to offer it

    BTW. Skipping the 16 bytes in the APP2 marker has nothing to do with the 16 bytes skipped when calling GdipGetPropertyItem. Just coincidence. The 16 bytes being skipped in the APP2 marker are:
    2 bytes for the chunk size
    12 bytes for the header: ICC_PROFILE + NullChar
    1 byte for the chunk ordering byte
    1 byte for the total count of ICC chunks
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  11. #11
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+

    A few points for reference only:

    Actually I was rather hesitant about the "to exclude 16 bytes". I said that because only by that it would bring a tally in the actual no. of bytes used: (i) had it been another file, a good one; and (ii) if FreeImage is used (value returned for the "Size" member of FIICCProfile).

    Once I had bumped into a strange scenario in which I had to obtain the profile bytes using GDIplus and FreeImage respectively for comparison purposes. GDIplus would let me pass using bytes obtained by FreeImage, but not bytes by GDIplus itself. I then looped through the individual bytes in the two arrays trying to ascertain where the difference lay, They were identical! I might still have the file, but I forgot which one it was now, because it must be a couple of years ago, otherwise I would attach the file here.

    There is another strange thing, not sure of any relevance here, just a mention.

    Public Type FIICCPROFILE '10 bytes 'FreeImage only
    Flags As Integer
    Size As Long
    Data As Long
    End Type

    "Flags" member is declared as Integer, not Long. However, when CopyMemory is called subsequently, it has to be "CopyMemory ......, 12", not "CopyMemory......, 10". Otherwise a crash will result, if something like "CopyMemory mAddress, ByVal typICCProfile.data, 4" is called to copy the size to "Data" field.

    For the above, someone explained that c/c++ compiler would inserts 2 slack bytes for proper alignment of the above "flags" member.

    If no ICC-conversion takes place, I would preserve the original ICC marker(s) on file Save. Sometimes the no. of ICC markers is well over 10. JPEG files can be rather untidy, sometimes the original file coders may place different markers at unexpected places - I had come across a file which started with 3 Comment markers.
    Last edited by Brenker; Sep 13th, 2014 at 10:26 AM.

  12. #12

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    Following up on that JPEG image... FYI: that jpeg image has 2 EXIF markers, split up by APP13 (Photoshop IRB) marker. The 2nd EXIF marker is XMP format

    The order of the APP markers follow: Marker, Marker offset from 0, Marker data length
    FFE0 (JFIF) 2 16
    FFE1 (EXIF) 20 5398
    FFED (Photoshop IRB) 5420 6658
    FFE1 (EXIF) 12080 21762
    FFE2 (ICC) 33844 576
    FFEE (Adobe) 34422 14

    1) Rearranged the app markers in several different combinations. In all cases, GDI+ failed to provide the profile
    2) Removed just the 1st EXIF marker and GDI+ returned the profile
    3) Removed just the 2nd EXIF marker and GDI+ failed again

    Without parsing the 1st EXIF marker (which I may do at a later time), I'm left to 2 possible conclusions for now
    1) First EXIF's chunk data is not what GDI+ is expecting
    2) GDI+ has issues loading multiple EXIF markers (don't think so?).

    FYI: I know that prior to Win7, GDI+ has problems returning profiles that are split among multiple chunks. But not applicable in that jpeg

    Anyway, more to investigate

    Update: I can parse the 1st EXIF marker just fine. At first glance don't see anything amiss. I have loaded other jpegs with multiple EXIF markers and they didn't make GDI+ choke. Must be something about that maker though; just don't see it right off. But I didn't take the time to verify every EXIF tag's offset is valid
    Last edited by LaVolpe; Sep 13th, 2014 at 01:23 PM. Reason: added marker info
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  13. #13
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+

    Seems not the case.

    Attached ZIP contains two JPEG files, one with 2 APP0 and the other with 2 APP1 on top of 2 APP0. In both cases, GDIplus doesn't have a problem processing ICC contained therein.

    A marker listing and an EXIF listing are shown below:
    Attached Images Attached Images   
    Attached Files Attached Files

  14. #14
    New Member
    Join Date
    Sep 2014
    Posts
    3

    Re: [VB6] Color Management with GDI+

    Hi!

    I found this thread looking for a way to parse an ICC profile's data from its contents in .Net/C#. It looks like it doesn't exist anywhere...

    Would you upload this project on GitHub or a similar website? So anyone could suggest code modifications...

    As requested in the first post, here is a 8 bit grayscale image with an embedded profile :
    Name:  grayscale-icc.jpg
Views: 2819
Size:  68.4 KB

  15. #15
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+

    To LaVolpe,

    I have done an exercise tonight, and can confirm that "to exclude first 16 bytes" is right basing on the following:

    -- I used a specific FreeImage's function to extract the subject ICC bytes and saved them to a file (remarks: I don't use FreeImage in my programs normally). File size being 560 bytes.

    -- I loaded the above-saved file and called GDIplus' OpenColorProfile(ICCProfile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING) and verified the validity of the ICC profile by ColorProfileValid().

    -- I compared the bytes from the above-said against the 560 bytes (after excluding first 16 bytes) in my previous posting, (i) the total bytes tally, (ii) the beginning portions are the same and (iii) the ending postions are identical.


    To cosmo0,

    I think if you want to keep your uploaded file intact (retaining ICC), you have to ZIP it and upload the ZIP file.


    Brenker
    Last edited by Brenker; Sep 19th, 2014 at 01:38 AM. Reason: To correct comso0's addressing name

  16. #16
    New Member
    Join Date
    Sep 2014
    Posts
    3

    Re: [VB6] Color Management with GDI+

    @Brenker: here is the zipped image.

    grayscale-icc.zip

  17. #17

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    thank you for the image. After initial analysis, my code won't process the color profile.

    If I am reading it correctly, it appears the color profile is for XYZ color space. If so, then the image is not in XYZ, but is in RGB color space after GDI+ loads it. Unlike CMYK where GDI+ can return the original pixel data in CMYK color space, do not believe GDI+ can return the original XYZ color space if applicable. Because the color profile has conversion from XYZ and the pixel data returned from GDI+ is not XYZ, the transformation fails. The color profile appears to be completely valid.

    Edited: Tried this with GDI+ v1.0, will try again with GDI+ v1.1 later today.
    When I modified my routines to create CImage (destination image) as 24bpp, then the color transformation did perform & did get a visible difference. Whether the difference is correct or not, not sure. The transformed result is on the right side below, image is not as dark. Windows Image/Picture viewer displayed same as the left side which is same as my code processed without the color profile applied. Can be difficult to see in the screenshot below since this site resizes the uploaded image, but the right side is lighter overall.

    Note: May be my fault when failed first time when I had both source/destination images as 8bpp. Have an idea that I will try later. In either case, appears can get the profile to be applied
    Attached Images Attached Images  
    Last edited by LaVolpe; Sep 19th, 2014 at 12:50 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  18. #18
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+

    For your reference:

    -- From marker SOF0, color model is Grayscale.

    -- From marker APP2, ICC color space is Grayscale.

    -- GDIplus has no problem processing ICC-conversion (on Vista).

    Screenshot shows YCbCr entry of original camera EXIF, and ICC-converted thumbnail.
    Attached Images Attached Images  
    Last edited by Brenker; Sep 19th, 2014 at 12:47 PM. Reason: Re: "From SOF0, color model is Grayscale"

  19. #19
    New Member
    Join Date
    Sep 2014
    Posts
    3

    Re: [VB6] Color Management with GDI+

    For info: I took a photo from my phone, opened it in Photoshop, and converted it to a grayscale profile. I'm not sure what it did exactly.

  20. #20

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    cosmo0 & Brenker: GDI+ v1.0 reports the JPEG as 8 bpp (going to assume grayscale, for now. I didn't ask GDI+ to give me the color table)
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  21. #21

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+

    Quote Originally Posted by cosmo0 View Post
    For info: I took a photo from my phone, opened it in Photoshop, and converted it to a grayscale profile. I'm not sure what it did exactly.
    When you have time, can you open your jpeg on your computer with Windows Paint or Picture Viewer? Does it look same as when loaded in PhotoShop or is one darker/lighter than the other? Curious.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  22. #22
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+

    Actually in the JPG, color model in SOF0 is Grayscale and color space in APP2 is also Grayscale. (At first I took my screenshot itself to find its SOF0 being RGB).

    Now I can confirm that actual colors in image are in Grayscale as well.

    So the JPG file itself is a perfect one.

    Screenshot below shows the palette.
    Attached Images Attached Images  
    Last edited by Brenker; Sep 19th, 2014 at 01:13 PM. Reason: Attach screenshot

  23. #23

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Modified sample project to include support for these cases:

    1) JPG ICC profile exists, but GDI+ doesn't return anything
    Not exactly happy with the patch which requires manually parsing 100% of all JPEGs that report no ICC profiles. Needs more thought.

    2) Allow 8 bit images to be processed (other than bmp/gif which were already supported).
    Not 100% comfortable with that patch & more samples/testing will be required
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  24. #24
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    LaVolpe,

    I've tested your updated copy; nice enhancement.

    There is a problem still regarding the one re post #9-13. In the updated version, the ICC-converted image is all black. I guess this is merely due to some kind of byte misalignment when you extract the ICC bytes. You can easily do a test, see if your starting position is at 33845 (1-based) and total bytes are 578 (marker, length field and data). (Remarks: Excluding 2 marker bytes, =576. and first 16 bytes thereafter, = 560)

    Not exactly happy with the patch which requires manually parsing 100% of all JPEGs that report no ICC profiles. Needs more thought
    Actually you don't have to. (1) The bug is gone on Win 7 upwards; (2) It only occurs at GdipGetPropertyItemSize(), not GdipLoadImageFromFile; and (3) You only need to try the work around when GdipGetPropertyItemSize() gives you a zero.

    Brenker
    Last edited by Brenker; Sep 20th, 2014 at 03:54 PM. Reason: Elaborate a little more to make it clearer

  25. #25

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    There is a problem still regarding the one re post #9-13. In the updated version, the ICC-converted image is all black.
    Hmmm. Might be a Win7 thing & I'll have to find the time to try to resolve that. On Vista and XP, that image at post #9 displays correct, both transformed and not. Out of curiosity, can you tell me what pixelformat your O/S reports that image as?

    If you are using Win7, then the routine to manually parse out the ICC wouldn't be invoked since you are saying that the ICC is returned via the GetProperty call?

    You only need to try the work around when GdipGetPropertyItemSize() gives you a zero
    Agreed. That's what the code is currently doing

    Edited: When I said "might be a Win7 thing", I meant a patch I put in to help Vista and lower, might have broken on Win7+
    Last edited by LaVolpe; Sep 20th, 2014 at 04:18 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  26. #26
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    can you tell me what pixelformat your O/S reports that image as?
    Per screenshot below, the image color model is "RGB" (remarks: had it been "CMYK", I wouldn't let it pass, because ICC color space is "sRGB". And vice versa.)

    If you are using Win7, then the routine to manually parse out the ICC wouldn't be invoked since you are saying that the ICC is returned via the GetProperty call?
    I am saying that if on Win7, GdipGetPropertyItemSize() wouldn't return you a zero; it would return a correct size.
    Attached Images Attached Images  

  27. #27

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Well, then. I'll look closer later today or tomorrow. The update I added to try to address the cases where GDI+ returns no ICC profile data (i.e., size < 16) is rather simple and does work on Vista & lower:

    1) Size of Property < 16 (therefore Profile size is zero)? If so, manually parse it out if it exists
    2) Size of Profile > size returned by GDI+? If so, manually parse it out

    If you are running Win7 and the size returned is correct, then the profile data being used is that which is returned from GDI+. This leads me to consider the problem is either in the 1st 4 bytes of data returned by GDI+ (should be 560), the 1st 4 bytes of the actual profile data (size of profile in little endian), or the pixelformat and BM_xxx flags are not working together. I won't know for sure until I get on a Win7 machine & that could be a bit.
    Last edited by LaVolpe; Sep 20th, 2014 at 06:02 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  28. #28
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    To be specific, below is the result obtained on your updated version, using the subject image file and on Vista. (Load file --> Click image to toggle to ICC-converted one)
    Attached Images Attached Images  
    Last edited by Brenker; Sep 20th, 2014 at 06:07 PM.

  29. #29

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Ok. Borrowed Win7 & ran the project using the image in #9. Worked as expected.

    Have you modified the code in any way or modifying the returned image in any way? Otherwise, don't understand why your image would be all black, other than not having AutoRedraw=False on the picbox.

    It is nice that Win7's version of GDI+ does return the ICC profile, intact.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  30. #30
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Have you modified the code in any way or modifying the returned image in any way?
    Honestly, I haven't even looked at any part of the code at all, not to say have it modifed (because I already have my own and I am satisfied with it).

    As said in my last posting, just drag drop the subject file --> click on image. That is all.

    Below shows the original GDIplus version on Vista.
    Attached Images Attached Images  
    Last edited by Brenker; Sep 20th, 2014 at 06:29 PM. Reason: Add screenshot of GDIplus version on Vista

  31. #31

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Should've read your post more closely. This time you are on vista?

    I managed to replicate the problem on Vista using v1.0 of GDI+. v1.1 worked as expected.
    This is the specific line of code causing the problem:
    Code:
    If GdipBitmapLockBits(hImage, lRect, ImageLockModeRead, tBmpData.PixelFormat, tBmpData) = 0 Then
    It is reporting a Win32Error error (GDI+ status code of 7). What's strange is that if I step thru that line & when it errors, simply execute that line again, immediately, it doesn't error the second time. Go figure.

    Gotta feeling this one is gonna be a bit iffy to debug.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  32. #32
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Apparently there must be quite some differences between our approaches. Notwithstanding that, the fact is that the strange phenonmenon occurs only on Vista, not Win7.

    For your info, I don't even have to call GdipBitmapLockBits() throughout my ICC-Processing function.

    Over the years I have come across some peculiar instances, e.g.

    In #11, I mentioned one and below is a re-cap:

    Once I had bumped into a strange scenario in which I had to obtain the profile bytes using GDIplus and FreeImage respectively for comparison purposes. GDIplus would let me pass using bytes obtained by FreeImage, but not bytes by GDIplus itself. I then looped through the individual bytes in the two arrays trying to ascertain where the difference lay. They were identical! I might still have the file, but I forgot which one it was now, because it must be a couple of years ago, otherwise I would attach the file here.

    In #26, I had "... remarks: had it been "CMYK", I wouldn't let it pass. And vice versa.".

    I have that validation because once I got a TIFF which was originated from CMYK color model, but the ICC colorspace being sRGB. It took me quite a while to trace to this to explain why the ICC-processed image looked funny.

  33. #33

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    I use LockBits for quite a bit of stuff. It is very efficient at getting to the image data in various pixel formats without having to render to some DIB & retrieving them that way. Haven't seen this specific error before. And it appears it is v1.0 related only; fixed in later version and builds. GDI+ simply doesn't like that JPG for ominous reasons

    If interested, here is the immediate patch. I will re-post the project a bit later
    change from:
    Code:
    If Not GdipBitmapLockBits(hImage, lRect, ImageLockModeRead, tBmpData.PixelFormat, tBmpData) = 0 Then
        ' open target image for writing
        If Not GdipBitmapLockBits(CMimage, lRect, ImageLockModeRead Or ImageLockModeWrite, rgbBmpData.PixelFormat, rgbBmpData) = 0 Then
    ...
    change to:
    Code:
    If Not GdipBitmapLockBits(hImage, lRect, ImageLockModeRead, tBmpData.PixelFormat, tBmpData) = 0 Then
        Call GdipBitmapLockBits(hImage, lRect, ImageLockModeRead, tBmpData.PixelFormat, tBmpData)
    End If
    If tBmpData.Scan0Ptr = 0& Then
        GdipDisposeImage CMimage: CMimage = 0&
    Else
        ' open target image for writing
        If Not GdipBitmapLockBits(CMimage, lRect, ImageLockModeRead Or ImageLockModeWrite, rgbBmpData.PixelFormat, rgbBmpData) = 0 Then
    ...
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  34. #34
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Needless to say that I do use GdipBitmapLockBits, otherwise how could I pass CMYK bytes for ICC-conversion. But that part is outside the ICC-processing itself.

  35. #35

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Quote Originally Posted by Brenker
    Apparently there must be quite some differences between our approaches. Notwithstanding that, the fact is that the strange phenonmenon occurs only on Vista, not Win7.
    Probably your approach is based on managing ICM via DCs? Render to DC then color transform from the DIB bits? My approach is an attempt to use no DCs or DIBs for transformation, just GDI+ and skipping the DIB middleman. And if not rendering to get the bits, need to get them another way: Lockbits. Of course, still need to use GDI functions to create & perform the transformation since the GDI+ flat API doesn't support ICM directly
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  36. #36
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Probably your approach is based on managing ICM via DCs?
    No. There is not a single DC involvment.

    Simply put, I pass a sRGB/CMYK DIB or a sRGB/CMYK byte stream, obtain ICC profile, and basing on it ask GDIplus to convert the bytes accordingly.

    On the Conversion screen (see the relevant screenshots in my earlier postingss), I show the key header pieces and it is upto the user to decide whether to do a conversion or not. If no conversion takes place, then the original JPEG ICC markers or PNG iCCP chunk will be preserved on Save (in the case of JPEG, EXIF as wel). I mentioned this point somewhere in one of the earlier postings.

    One last item to mention, for a 8-BPP JPEG, like the one from cosmo0, I detect whether the current image is still Grayscale on Save, if not, then the original ICC would not be preserved even though no ICC-conversion has taken place.
    Last edited by Brenker; Sep 20th, 2014 at 09:16 PM. Reason: Add 3rd & last paragraphs

  37. #37

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Quote Originally Posted by Brenker View Post
    Simply put, I pass a sRGB/CMYK DIB or a sRGB/CMYK byte stream, obtain ICC profile, and basing on it ask GDIplus to convert the bytes accordingly.
    Clever enough.

    I challenged myself to avoid extra GDI objects if needing/wanting to use GDI+ for anything. GDI+ makes it easy to load a png & tiff, therefore, decided to use GDI+ vs lots of extra code to manually load/decompress those image types or relying on 3rd party tools. GDI+ also makes it easy to extract ICC profiles when it works as planned; though I can easily parse ICC data from these formats without GDI+ help.

    Like most projects, more than one way to get the same result.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  38. #38
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Our last two postings crossed. I have meanwhile added two paragraphs to my previous one. That should be about to close our discussion for now.

  39. #39
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    There is something funny about GDIplus on Win 7.

    If you load cosmo0's JPEG file in Vista, you get a color count of 256. However, if you do the same on Win 7, you have only 16.

    This means, on Win 7, the ICC-converted image of it has only 16 colors.

  40. #40

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] Color Management with GDI+ (updated 20 Sep 14)

    Quote Originally Posted by Brenker View Post
    If you load cosmo0's JPEG file in Vista, you get a color count of 256. However, if you do the same on Win 7, you have only 16.
    Interesting. Will take a look-see this weekend

    Note to self: Rework routines to better allow GDI/GDI+ working together. Example
    1. Load source image into GDI+
    2. Get size of ICM & create array of IMC size + 124 (BMPINFOV5 size)
    3. Read ICM into tail end of array
    4. Complete 1st 124 bits of array to comply with v5
    5. Create 2nd GDI+ image to hold color managed pixel data
    6. Get graphics context & then DC from the dest image (GdipGetImageGraphicsContext, GdipGetDC)
    7. Apply target profile to target dc (GetStandardColorSpaceProfileW, SetICMMode)
    8. Use SetDIBitsToDevice to target DC
    9. GdipReleaseDC, GdipDeleteGraphics
    Done
    Last edited by LaVolpe; Jun 26th, 2015 at 01:50 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width