Results 1 to 26 of 26

Thread: [RESOLVED] Change the color of the drawing

  1. #1

    Thread Starter
    Addicted Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    231

    Resolved [RESOLVED] Change the color of the drawing

    Say I have an icon that has a certain design and color. And I want to change a color of this icon. How do I do?

    In the attachment I have an icon with blue coloring, say I want to replace the blue with green ... without deforming the design is it possible?


    Edit: Sorry, one more detail ... this icon will be in a picturebox or image control, and it will be in a form.
    Attached Images Attached Images  

  2. #2
    PowerPoster
    Join Date
    Feb 2017
    Posts
    3,209

    Re: Change the color of the drawing

    But, do you need both icon colors or just the one changed?

  3. #3

    Thread Starter
    Addicted Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    231

    Re: Change the color of the drawing

    I need to change the fill color at run time. The user chooses the color and the program changes the color.

  4. #4
    PowerPoster
    Join Date
    Feb 2017
    Posts
    3,209

    Re: Change the color of the drawing

    Search for the API SetColorAdjustment.

    Of course that's one option, I don't mind it is the only one.

  5. #5
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: Change the color of the drawing

    Icon or bitmap? It matters.

    It can't be a rendered bitmap since you specified PictureBox or Image control.

    Sounds like what you really have is a StdPicture object but you haven't told us explicitly what it wraps. You say "icon" but do you mean "icon" or might it be something else?

    Icons are more work than bitmaps.

  6. #6
    PowerPoster
    Join Date
    Feb 2017
    Posts
    3,209

    Re: Change the color of the drawing

    I assumed that it was an image that can be converted to a bitmap, but if it needs to remain as icon (in a StdPicture) it is a different issue.

  7. #7

    Thread Starter
    Addicted Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    231

    Re: Change the color of the drawing

    It is truly a StdPicture. However, the origin of the image comes from an icon.

    Edit: There are so many challenges in programming.

  8. #8
    PowerPoster
    Join Date
    Feb 2017
    Posts
    3,209

    Re: Change the color of the drawing

    But you still don't answer the the important point: if the image needs to remain as an icon or not.

  9. #9
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: Change the color of the drawing

    Icons also have transparency issues that complicate matters.

  10. #10
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: Change the color of the drawing

    Other issues:

    It might be a PNG icon image.
    Recoloring may increase the color depth.

    Even ignoring those two issues it might take nearly twice the API calls to do this for an icon rather than a bitmap. A normal icon contains either two bitmaps or a PNG.

  11. #11
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: Change the color of the drawing

    Example that works with bitmaps:

    Name:  sshot.png
Views: 127
Size:  3.0 KB

    Click in the image to pick the old color, click on the new color swatch for a color dialog to pick the new color.
    Attached Files Attached Files

  12. #12
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: Change the color of the drawing

    Took a stab. Seems to work.

    May not be ideal, might have handle leaks I didn't track down and lacks thorough error checking just like the bitmap version. But going over it for bugs and adding more checking might be a good way to learn.


    Changes:

    Found hIcon leak, fixed. Also optimized things, reducing some code (no longer creating another copy of the mask bitmap, re-using it).
    Attached Files Attached Files
    Last edited by dilettante; Mar 8th, 2021 at 05:37 PM. Reason: New attachment.

  13. #13

    Thread Starter
    Addicted Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    231

    Re: Change the color of the drawing

    Quote Originally Posted by dilettante View Post
    Took a stab. Seems to work.
    Yeah ... it went really far ...

  14. #14

    Thread Starter
    Addicted Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    231

    Re: Change the color of the drawing

    Quote Originally Posted by dilettante View Post
    May not be ideal, might have handle leaks I didn't track down
    What are these leaks?

  15. #15
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: Change the color of the drawing

    GDI objects are referenced by "handles." These almost always need to be freed up explicitly when no longer needed. Otherwise memory gets eaten up over time or you might even exceed the limit and crash the system.

    GDI Objects

    GDI objects support only one handle per object. Handles to GDI objects are private to a process. That is, only the process that created the GDI object can use the object handle.

    There is a theoretical limit of 65,536 GDI handles per session. However, the maximum number of GDI handles that can be opened per session is usually lower, since it is affected by available memory.

  16. #16

    Thread Starter
    Addicted Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    231

    Re: Change the color of the drawing

    Would these objects be stdPicture?

  17. #17
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: [RESOLVED] Change the color of the drawing

    I still see leaks, but they seem to be phantoms.

    For example creating a DC creates a solid color brush but GDI caches solid color brushes and reuses them a needed. It looks like you also get cached 1x1 pixel bitmaps when you create DCs. You can't clean them up.

  18. #18
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: Change the color of the drawing

    Quote Originally Posted by Episcopal View Post
    Would these objects be stdPicture?
    They aren't "objects" in the VB or COM sense. They are GDI objects, a different animal.

    But a StdPicture "object" does wrap one or more GDI "objects."

  19. #19
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: [RESOLVED] Change the color of the drawing

    This all gets far simpler if you didn't use icons, and even simpler yet if you didn't use Image controls.

    For example, using a PictureBox or UserControl instead, you can easily use PaintPicture, Render, etc. to draw an icon StdPicture there. Once there it is simpler to recolor the resulting image just using VB statements (no API calls). That can be slow, but then even using API calls to recolor is a lot simpler. Image controls do not support VB drawing/painting operations.

    Think of Windows as a large swimming pool. You have wandered under the rope that marks the shallow end.

  20. #20

    Thread Starter
    Addicted Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    231

    Re: [RESOLVED] Change the color of the drawing

    Diletante ........ thank you very much

  21. #21
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: [RESOLVED] Change the color of the drawing

    This may be good enough for your needs as is.

    Future readers:

    Somebody may come along and tighten up the code I offered, add more error checks (X and Y bounds checks, API call return code processing, etc.), squash silly bugs, and so on.

    Also, I'm doing the recoloring by filling a new color bitmap with the new color and then TransparentBlt()-ing the old color bitmap over it using the old color as the transparent color.

    There are other possibilities too, for example: fetching with GetDIBits(), then looping over the pixel bits replacing the color one pixel at a time, then creating the new color bitmap using CreateDIBSection(), then copying the recolored bits into that bitmap. That gets you a DIB though, and I'm not sure that CreateIconIndirect() will accept a DIB or if it does whether the mask bitmap must be a DIB too.

    There is also GDI+ using GdipSetImageAttributesRemapTable(), etc. That's another alternative using quite different code. I suspect the GDI approach I used above might be faster though.

  22. #22
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    3,022

    Re: [RESOLVED] Change the color of the drawing

    Quote Originally Posted by dilettante View Post
    That gets you a DIB though, and I'm not sure that CreateIconIndirect() will accept a DIB or if it does whether the mask bitmap must be a DIB too.
    It does accept 32-bit premultiplied alpha DIBs and the mask color has to be a dummy 1-bit monochrome completely transparent one (for compatibility reasons I guess) otherwise CreateIconIndirect fails.

    Code:
        With uInfo
            .fIcon = 1
            .hbmColor = hDib
            .hbmMask = CreateBitmap(sngTargetWidth, sngTargetHeight, 1, 1, ByVal 0)
        End With
        hIcon = CreateIconIndirect(uInfo)
        With uDesc
            .lSize = Len(uDesc)
            .lType = vbPicTypeIcon
            .hBmp = hIcon
        End With
        '--- IID_IPicture
        aGUID(0) = &H7BF80980
        aGUID(1) = &H101ABF32
        aGUID(2) = &HAA00BB8B
        aGUID(3) = &HAB0C3000
        If OleCreatePictureIndirect(uDesc, aGUID(0), 1, pvLoadPicture) <> 0 Then
            GoTo QH
        End If
    cheers,
    </wqw>

  23. #23
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: [RESOLVED] Change the color of the drawing

    Good to know, but I don't think an Image control can handle an XP format icon very well. The transparent areas turn black when I try it, but I wasn't using a CC6 manifest either so maybe that's the issue.

  24. #24
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    3,022

    Re: [RESOLVED] Change the color of the drawing

    Quote Originally Posted by dilettante View Post
    Good to know, but I don't think an Image control can handle an XP format icon very well. The transparent areas turn black when I try it, but I wasn't using a CC6 manifest either so maybe that's the issue.
    It's the StdPicture's Render method *not* using DrawIconEx for no apparent reason and it tries to interpret ICONINFO's bitmap and mask on it's own.

    Notice how Wine uses custom render_masked_bitmap for PICTYPE_ICON and this is totally not reversed from oleaut32.dll -- just the bugs are the same :-))

    cheers,
    </wqw>

  25. #25
    PowerPoster
    Join Date
    Feb 2006
    Posts
    22,314

    Re: [RESOLVED] Change the color of the drawing

    I understand the reason, but like it or not it's there. So I doubt anyone stuffing icons into an Image control is going to be dealing with 32-bpp XP icon images.

    I guess if they're willing to use a PictureBox or a custom UserControl to display those properly then my code above is too simple.

  26. #26
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    3,022

    Re: [RESOLVED] Change the color of the drawing

    Yes, it's an unfortunate shortcoming of the Render method.

    That's the only reason I cobbled up a single-file poor man's AlphaBlendImage control -- load and display 32-bit premultiplied alpha DIBs stuffed innside an icon in an StdPicture.

    cheers,
    </wqw>

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