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

Thread: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

  1. #1

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Resolved [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Hi Cairo Squad,
    I've been testing another autobuilder, but came to an abrupt halt.
    Short version, handmade Photoshop sketch tests, thought they looked particularly cool, made a Cairo re-assembler to make many, however, colours were horribly skewed from the Photoshop ideals (bright areas dropped, colourization too hot etc). I've had to reassess the builder and am now starting from scratch.
    I just noticed one thing, that would make everything easy peasy. Hue Shifting.
    I was wondering if people know how to do this in Cairo?
    This is what you do in Photoshop.
    Name:  Potion Test.jpg
Views: 1015
Size:  24.4 KB
    Saturation is easy as you only need to place a grey surface over the original image. But actual hue shifting? I tried various Photoshoppy addition layers, like adding a hue layer in a different colour, but it's all wrong. So I'm wondering if Cairo has a way of hue shifting? The reason I ask, is because if I add a hue layer to the original image it overwrites ALL hues, meaning a red potion with orange glow becomes soley green for example. It looks pretty foul to be honest. Basically the underlayer with multiple colours becomes a bland single colour.

    These are my handmade Premade-Proper-Photoshop-Pixel-Potions-Picked-A-Pepper-Or-Two I'm trying to replicate. Thanks for help!
    Name:  Potion Wall.jpg
Views: 1024
Size:  97.2 KB

  2. #2
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    If I understand correctly you want to be able to change the hue of an image without needing Photoshop. Perhaps you want your own code to do it through Cairo. Now I can't say whether Cairo can do it, I'll leave that to Olaf since he is the resident Cairo expert.

    However, in the event that Cairo can't do what you want, I offer this: Changing the hue of an image, while I won't say it's easy, it's not exactly difficult either. We're all used to dealing with colours using the RGB colour space however, it is not the only colour space. There are many colour spaces and the ones you need to be dealing with are the HSL or HSB colour spaces. So what you do is you get all the pixel values of the image which will be in RGB format and from there you have to convert all of them to HSL or HSB from there you can change the hue values of each pixel by adding or subtracting to and from the hue value of each pixel.

    It should be quite easy to find an algorithm to convert from RGB to HSL/HSB online if this Cairo thing doesn't work out and you have to do it yourself. Also, I wrote a small application for recolouring sprites which does this through the HSL colour space. You can check it out here if you want. It's written in VB.Net but perhaps you can look at it for ideas. It uses no 3rd party image libraries or anything like that for recolouring sprites so the code is all there showing how to do it.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  3. #3
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,738

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Maybe you can get some ideas from Tanner Helland's Photodemon
    It's all written in VB6, and open-source

  4. #4

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Thanks Niya, though I can't read your files... I don't have .Net installed anymore. Can I open one in word pad perhaps, which file?
    Name:  Thats VBPox Isn't it.jpg
Views: 997
Size:  114.1 KB

    Thanks Arnoutdv I'll take a looksee.

    Though I was looking at other code chunks to slide HSB around, but it was all Python, C, Sea-flea and god knows what else. I'm not proficient to understand the complexities of what they were doing this time. Normally one can guess the similar components but nothing was apparent. I'll keep looking until I submit to my,,,, *drum roll*

    A Last Minute Trashy Workaround! Tadah!

    Name:  Lazy Work Around.jpg
Views: 1016
Size:  67.5 KB

    Behold in all it's god awful glory. Ligthen layers of R(Normal), G and Beeeee. I think I can randomize all these to make various shifts, sort of. It kind of actually works much to my surprise. If nothing is apparent I'll just use this dodgy method.

  5. #5
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Well just to be clear, you want the ability to recolour sprites by changing the hue, right? So you can create different colour bottles from a single base, is this right? I was guessing that is what you were looking for based on your OP but I wasn't 100% sure.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  6. #6

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by Niya View Post
    Well just to be clear, you want the ability to recolour sprites by changing the hue, right? So you can create different colour bottles from a single base, is this right? I was guessing that is what you were looking for based on your OP but I wasn't 100% sure.
    Yes.

    The trashy workaround I 'just' thought up a moment ago does this, sort of... It's not precisely predictable or code worthy, but the light levels stay perfect as do the hue shift. <- I have not been able to do this via Cairo or Photoshop 'Flat Layering' yet.
    In the workaround, if I randomize alpha on the RGB layers in Cairo, that will be enough to alter the bottles appearance. I tried mucking around and all the vibrant colours stayed perfect, complete with tonal shifts. It's like fixing a car with a sledgehammer though...

  7. #7
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Ok, so to be extra sure this is what you want to be able to do?

    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  8. #8

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Yeah, just an entire 'image' or 'Cairo surface' hue shift. I don't need anything fancy.

    Cairo is preferable, if it's available as a thing. Cairo seems to have a lot of built in art functions, but I haven't come across hue shift yet, only hue layer add.

  9. #9
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by -Corso-> View Post
    Yeah, just an entire 'image' or 'Cairo surface' hue shift. I don't need anything fancy.

    Cairo is preferable, if it's available as a thing. Cairo seems to have a lot of built in art functions, but I haven't come across hue shift yet, only hue layer add.
    Tell me, does Cairo allow you to access pixel data from it's surfaces? If that's the case, all you have to do is convert those pixel values from RGB to HSL or HSB. You can then set the hue of the pixels, convert them back to RGB and write them to the Cairo surface.

    Also, how are you using Cairo? Are you using it through Olaf's RichClient library or are you using it through something else? The reason I ask is because if it's from RC5/6 then perhaps Olaf can help with this.

    I could show you how to do it manually but it would take me forever write a working sample in VB6 since I'd have to rely on what I know which is GDI and that requires a lot of tedious boilerplate. I'm not looking forward to that at all Olaf could probably produce VB6 code for this far faster than I ever could.
    Last edited by Niya; Jun 2nd, 2022 at 12:32 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  10. #10

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Yes, RC6 does allow you to read and write pixel data. (BindToArray). I can do that to grab RGB and Alpha. Ah, so I just need to find the code to switch that to HSV. Nice!

  11. #11
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    https://www.geeksforgeeks.org/progra...v-color-model/

    There's some c# ccode thtere that you might be able to adapt to your needs.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  12. #12
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Ok I made an extremely barebones sample that demonstrates how to change an image's hue. Here's a 40 second video demonstrating it so you see what it looks like:-


    I wanted to do the demo in VB6 but unfortunately I was unable to quickly find information on how to load an image from disk and access it's pixel data using RC6's Cairo. I didn't want to spend all day trawling these boards looking for that information. GDI was also out of the question since it would require a tonne of boilerplate I'd have to spend up to an hour writing and testing or ripping from old VB6 projects I haven't touched in like a decade plus. Instead I just banged it out in about 30 minutes in VB.Net.

    Fortunately though, the important parts are extremely easy to understand and translate to VB6. I'll leave it to you to figure out all the Cairo stuff in VB6.

    Now the core of all this as I've said is converting from RGB to HSB or HSL and back. I chose HSB since it's a tad bit simpler than HSL. Here is the code for converting RGB to HSB and back:-
    Code:
    Public Structure HSB
        Public Sub New(hue As Integer, saturation As Double, brightness As Double)
            Me.Hue = hue
            Me.Saturation = saturation
            Me.Brightness = brightness
        End Sub
        Public Property Hue As Integer
        Public Property Saturation As Double
        Public Property Brightness As Double
    
        Public Overrides Function ToString() As String
            Return $"Hue = {Me.Hue.ToString}, Saturation = {Me.Saturation.ToString}, Brightness = {Me.Brightness.ToString}"
        End Function
    
    End Structure
    
    
    Public Class ColorConverter
        Public Shared Function ColorToHSB(ByVal c As Color) As HSB
            Return RGBToHSB(c.R, c.G, c.B)
        End Function
    
        Public Shared Function RGBToHSB(ByVal R As Byte, ByVal G As Byte, ByVal B As Byte) As HSB
    
            Dim d_r As Double = R / 255
            Dim d_g As Double = G / 255
            Dim d_b As Double = B / 255
    
            Dim max As Double = {d_r, d_g, d_b}.Max
            Dim min As Double = {d_r, d_g, d_b}.Min
            Dim diff As Double = max - min
    
            Dim h As Integer
            Dim s, v As Double
    
            If max = min Then
                h = 0
    
            ElseIf max = d_r Then
                h = (60 * ((d_g - d_b) / diff) + 360) Mod 360
    
            ElseIf max = d_g Then
                h = (60 * ((d_b - d_r) / diff) + 360) Mod 360
    
            ElseIf max = d_b Then
                h = (60 * ((d_r - d_g) / diff) + 360) Mod 360
            End If
    
            If max = 0 Then s = 0 Else s = diff / max
    
            v = max
    
            Return New HSB(h, s, v)
        End Function
    
        Public Shared Function HSBToRGB(ByVal hsb As HSB) As Color
            Return HSBToRGB(hsb.Hue, hsb.Saturation, hsb.Brightness)
        End Function
    
        Public Shared Function HSBToRGB(ByVal hue As Integer, ByVal saturation As Double, ByVal value As Double) As Color
            'JavaScript algorithm
            '===============================================
            '  Const HSBToRGB = (h, s, b) >= {
            '  s /= 100;
            '  b /= 100;
            '  Const k = (n) >= (n + h / 60) % 6;
            '  Const f = (n) >= b * (1 - s * Math.Max(0, Math.Min(k(n), 4 - k(n), 1)));
            '  Return [255 * f(5), 255 * f(3), 255 * f(1)];
            '};
            '===============================================
    
            Dim k = Function(n As Double) (n + hue / 60) Mod 6
            Dim f = Function(n As Double) value * (1 - saturation * Math.Max(0, {k(n), 4 - k(n), 1}.Min))
    
            Return Color.FromArgb(255, 255 * f(5), 255 * f(3), 255 * f(1))
        End Function
    End Class
    The above is VB.Net code I know but it's really nothing more than mathematical formulas really. It should be very trivial to convert this to VB6.

    Apply it to an image is also very trivial. Here is the VB.Net code I used:-
    Code:
        Public Sub SetImageHue(ByVal img As Bitmap, ByVal hue As Integer)
    
            'Lock the Bitmap object to access it's bits
            Dim bpData = img.LockBits(New Rectangle(0, 0, img.Width, img.Height), Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format32bppArgb)
    
            Dim A, R, G, B As Byte
    
            For i As Integer = 0 To (bpData.Width * bpData.Height) - 1
    
                'Read the colour components of each pixel
                'from the Bitmap
                B = Marshal.ReadByte(IntPtr.Add(bpData.Scan0, i * 4))
                G = Marshal.ReadByte(IntPtr.Add(bpData.Scan0, i * 4), 1)
                R = Marshal.ReadByte(IntPtr.Add(bpData.Scan0, i * 4), 2)
                A = Marshal.ReadByte(IntPtr.Add(bpData.Scan0, i * 4), 3)
    
                'Convert the pixel from the RGB colour space to
                'the HSB colour space.
                Dim hsb = ColorConverter.RGBToHSB(R, G, B)
    
                'Set the hue of the pixel
                hsb.Hue = hue
    
                Dim c As Color = ColorConverter.HSBToRGB(hsb)
    
                'Write the pixel back to the image
                Marshal.WriteInt32(IntPtr.Add(bpData.Scan0, i * 4), c.ToArgb)
    
            Next
    
            'Unlock the bitmap
            img.UnlockBits(bpData)
        End Sub
    The above is a function that sets the Hue of a Bitmap. It's very simple. You just enumerate all of the pixels in the image, convert the RGB components to HSB, set the hue you want, convert it back to RGB and write the new RGB values back to the image. Very easy stuff.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  13. #13

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Thanks Niya. I'll examine this in detail. I'm actually dead tired and sore after a hospital visit, plus I have to go back in a few days. I'd like to write up the Cairo version using your formula as it's a good way for me to learn it for other colour adjustments in the future. Just going to rest for a few days before I post that though.
    While there I coded up the lazybones version of mine too, for the, just in case scenario.
    Thanks for posting.

  14. #14
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by -Corso-> View Post
    I'd like to write up the Cairo version using your formula...
    Before you dive into your own Pixel-Loops, please check whether the function below -
    (ApplyHueTo(...) is sufficient).

    Code:
    Option Explicit
     
    Private CC As cCairoContext 'our global BackBuf-CC (derived from a Form-covering Surface)
    
    Private Sub Form_Load()
      Dim Src As cCairoSurface
      Set Src = Cairo.ImageList.AddImage("Grey_Src", "c:\temp\potion_greyscale.png", 128, 128)
      
      Cairo.ImageList.AddSurface "Hue_Green", ApplyHueTo(Src, vbGreen)
      Cairo.ImageList.AddSurface "Hue_Yellow", ApplyHueTo(Src, vbYellow)
      Cairo.ImageList.AddSurface "Hue_Magenta", ApplyHueTo(Src, vbMagenta)
      Cairo.ImageList.AddSurface "Hue_Cyan", ApplyHueTo(Src, vbCyan)
     
      Me.Move Left, 0, Width, Screen.Height
    End Sub
    
    Private Sub Form_Resize()
      ScaleMode = vbPixels: AutoRedraw = True
      Set CC = Cairo.CreateSurface(ScaleWidth, ScaleHeight).CreateContext
      ReDraw
    End Sub
    
    Private Sub ReDraw()
      CC.Paint 1, Cairo.CreateCheckerPattern(8, &H333333)
      
        Dim i&
        CC.RenderSurfaceContent "Grey_Src", 0, i * 128: i = i + 1
        CC.RenderSurfaceContent "Hue_Green", 0, i * 128: i = i + 1
        CC.RenderSurfaceContent "Hue_Yellow", 0, i * 128: i = i + 1
        CC.RenderSurfaceContent "Hue_Magenta", 0, i * 128: i = i + 1
        CC.RenderSurfaceContent "Hue_Cyan", 0, i * 128: i = i + 1
     
      CC.Surface.DrawToDC hDC: Refresh
    End Sub
     
    Private Function ApplyHueTo(Src As cCairoSurface, ByVal Color As Long) As cCairoSurface
      Dim CC As cCairoContext, TmpSrf As cCairoSurface
      'we have to do this in two steps (because HSL-Operations do not support Alpha)
      Set CC = Cairo.CreateSurface(Src.Width, Src.Height).CreateContext
          CC.Paint 1, Cairo.CreateSolidPatternLng(vbBlack)
          CC.RenderSurfaceContent Src, 0, 0
          
          CC.Operator = CAIRO_OPERATOR_HSL_COLOR
          CC.Paint 1, Cairo.CreateSolidPatternLng(Color)
      Set TmpSrf = CC.Surface 'store the result of Step 1 in a Tmp-Surface
      
      'Ok, now step 2 (Masking of the TmpSrf with the original Src)
      Set CC = Cairo.CreateSurface(Src.Width, Src.Height).CreateContext
          CC.SetSourceColor Color
          CC.MaskSurface Src
            
          CC.SetSourceSurface TmpSrf
          CC.MaskSurface Src
          
      Set ApplyHueTo = CC.Surface
    End Function
    It produces these results (from a GreyScale-Alpha-Source):
    Name:  HueChanges.png
Views: 907
Size:  88.1 KB

    Edit: added a Project-Zip -> Potions.zip

    HTH

    Olaf
    Last edited by Schmidt; Jun 3rd, 2022 at 02:23 PM. Reason: Added a complete Project as a Zip

  15. #15

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Hi Olaf,

    I was getting the similar results with a basic Operator = CAIRO_OPERATOR_HSL_SATURATION to my original picture. (Because it already has colour tones in it, which allows the hue shift.)
    The reason for Hue 'Shift', and not 'Hue Overwrite' is to preserve the 'other' colours present in the original.
    For example, if I add a yellow tint to your red potion bottle original, the tint vanishes to a single colour.

    Seen here, the red/yellow bottles' lower incarnations are flat. Not the desired result.

    Name:  Overwritten Hues.jpg
Views: 921
Size:  61.3 KB

    It means brown beer bottles with golden highlights, or an orange potion with an inky purple seeping in become flat too. This is what was happening with the very first autobuilder, now scrapped.

    I'll continue on the hue shift integration in a few days when I'm better rested.

  16. #16
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Olaf's solution seems to require a greyscale base image, not one with colour. Is there some reason you can't start the "hue shifting" process with a greyscale image? Look at his code, it seems it is not so much changing the hue of the image as it is performing a blend operation of the grayscale image onto a coloured background. Such an approach would be a tad bit unpredictable if you start with a coloured image.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  17. #17
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Shouldn't the bottle and cap or stopper be one image, and the "potion" contents another?

    Then after tinting and adjusting saturation and brightness of the contents, first render the contents and then render the transparent bottle in front of it? A little crude and requires that the bottle be flat-on to the eye so its bottom renders as just a thick line... but at least the glass and stopper don't end up tinted or brightness distorted and you don't get any awkward tinted "glow."

    If the ultimate goal is a transparent PNG the canvas should be all transparent pixels before rendering I suppose.

    I think all of this can be done with plain old GDI32 calls (including loading the source PNG images as bitmaps)... except encoding the result in PNG format. Much of the heavy lifting could be done using SetColorAdjustment().

    As a bonus this can all be done using DDBs and compatible DCs. That way GDI Scaling can be used to keep your UI from falling apart under High DPI (even multimonitor mixed DPI).

  18. #18
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Ok, I'm wrong. StretchBlt() does not preserve the alpha channel even for a 32bpp DC and Bitmap so SetColorAdjustment() is not available.

    Spoke too soon. It is true but there is a hack around it. I already have to loop over the bitmap bits to premultiply the alpha anyway.
    Last edited by dilettante; Jun 4th, 2022 at 05:16 AM.

  19. #19

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Name:  Autobuild breakdown.jpg
Views: 767
Size:  70.4 KB
    Here's a quick breakdown of the potion assembly. Note, you must NOT start with a greyscale image. That is forbidden!
    Puh! Dirty Hobbitses and their greasyscales!
    Name:  filthy-little-hobbitses.jpg
Views: 593
Size:  54.0 KB

    There are so many tonal colours in the solution that it's too much work to recreate in Cairo from a greyscale.

    Basically, I make a huge bottle at 600px^2 and use Photoshop layering effects to get what I want(what I think looks coolest). Basically, that initial bottle body is just a white blob of pen strokes and fill, Photoshop does the illumination, gradients, tone, colour variance on the fly. (Again, thanks to it's Layering Effects and proficiency. *Smug Smug*) So if I want a new bottle, I only draw a white blob shape. Same with all the other components leather, neck, stopper, insignia.

    Those layers are then re-assembled on Cairo, with many stoppers, leather, bodies, necks and so on. Unlimited Potion Works.
    All randomly chosen, same as the Cairo Rock Builder.
    But, I do want the bottle contents to have a full spectrum colour array. Normally one uses hue shifting as it doesn't interfere with the white glass reflect or outline, that's critically (artistically) important.
    Hence why I'm tracking it down, but I'm on massive loads of painkillers today, so I'm just falling asleep at the keyboard instead.
    Thankfully, I've got the code prepped and ready to input to use RGB separated layers which ultimately ends up in the same as what hue shifting does.
    Before all of that, I run some specialised automations through Photoshop to produce the potion bottle components with further lighting etc, and that's a whole other potion bottle of fishsauce.

    Name:  Component Born Potions.jpg
Views: 785
Size:  18.4 KB Fishsauce takes no time to draw, less than a moment.

    So, greyscale starting image is BAD! Begone wicked thoughts of monotoness! Foul demoness!
    Last edited by -Corso->; Jun 4th, 2022 at 05:21 AM.

  20. #20
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    I think exploring Tanner Helland's PhotoDemon is an excellent idea.

    However, I just think of hue shifting as a RyGcBmRyGcBm... circle (red-yellow-green-cyan-blue-magenta-red...). If we imagine our three RGB pixel values (0 to 255), and think of a sum of them, it's just rotating those values in a way that keeps their sum the same, gradually shifting which is higher and which is lower, etc.

    I suppose the differentials (between the RGB values) must also stay the same, or it just all goes to gray.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  21. #21
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Yeah, it sounds like tinting isn't the goal at all. Probably colorspace rotation shifting each pixel's hue by the same amount in a circular manner.

  22. #22
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by dilettante View Post
    Yeah, it sounds like tinting isn't the goal at all. Probably colorspace rotation shifting each pixel's hue by the same amount in a circular manner.
    I strongly suspect this as well.

    I'm currently examining the the code Olaf posted to try and figure out how to reproduce my VB.Net sample in VB6 using RC6's Cairo objects which does exactly as you said, rotates the hue of the image. This is the same strategy I used in the PixelPainter application I also mentioned in this thread. It's basically a stripped down version of GIMP's Colourize feature. It's typically used to recolour sprites and such for games. For example if you have sprites of a guard in red uniform, you can shift the hues to change the colour of the uniform to say, green or brown.

    I'll post that when I'm done. I have to kind of feel my way around Cairo by trial and error because RC6's implementation of Cairo is not documented. A lot of guess work but I'm making progress.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  23. #23
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Try this:-


    I've finally been able to figure out a bit about using Cairo thanks to the code Olaf posted earlier.

    The above demonstrates a VB6 version of the VB.Net version I posted earlier. This one uses Cairo and a translated version of the VB.Net code to perform hue shifting. See attachment for the application.
    Attached Files Attached Files
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  24. #24

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Niya, reading your code is like....
    Name:  VB6 Loves you too.jpg
Views: 722
Size:  75.6 KB

    Not the hue shift I was looking for. *Finger motion*. Carry on.
    Name:  Not the hue shift you were lookiong for.jpg
Views: 762
Size:  44.6 KB

    Meanwhile, the Methstar is nearing completion.... R G B are now in separate folders. Photoshop automations are all complete. I just need to go sleep and deal with the nested multiple file loading crap again.

  25. #25
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by -Corso-> View Post
    Niya, reading your code is like....
    Name:  VB6 Loves you too.jpg
Views: 722
Size:  75.6 KB
    Yea it was very painful doing that in VB6 to be honest. It took me like 20 to 30 minutes to do the VB.Net version and it took me nearly all a day to do that VB6 version. I kept getting side tracked by VB6's various limitations because I'm no longer used to them. Plus I had to do a lot of trial and error to try and guess my way through Cairo.

    Quote Originally Posted by -Corso-> View Post
    Not the hue shift I was looking for. *Finger motion*. Carry on.
    Name:  Not the hue shift you were lookiong for.jpg
Views: 762
Size:  44.6 KB
    Based on that image, it works exactly as I expected. What's wrong with it?
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  26. #26

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Name:  Alderan should be nuked.jpg
Views: 771
Size:  72.5 KB
    Ok, to explain, that slider function has overwritten all tones in the image when activated. It's 'looks' like a hue shift functionally speaking, but it actually overwrites first, then your slider hue shifts. So the image was overpainted really. Which is what the first autobuilder and Olaf's version does.

    The picture below, blue bottle is what true hue shifting is. Notice the darker blue liquid near the top? If I scroll the hue shift slider in Photoshop, it maintains the 'other' variant colours. And the others are there for showing it further. So, really speaking, no overpaint, actual 'shift'.

    It's tricky, but I was hoping Cairo had some sort of inbuilt function for sliding colours, but doesn't look like it.

  27. #27
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Ak ok. I think I know what you want. I might need to make some minor changes to how the hue is applied. I can't promise it would achieve the effect you want but I'm willing to give it a try.

    Can you provide me with an image of original bottle by itself?
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  28. #28

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Very happy to encourage users back to VB6.

    Attached are some rough PNG's. Normally I'd remove the leather but it doesn't matter in this instance. Techgnome's link has the RGB HSV conversion code. So I should really concentrate on that. But various painkillers are making my brain mush.

    I think it's just a matter of going over each pixel, pulling it's R,B,G values, convert those to HSV via Techgnome's link, adjusting the H value by a set amount, then converting back to RGB, then writing over the original surface/image.

    I'd have to dig up my BindToArray code once more....

    (Is this how one attaches images here???)
    Attached Images Attached Images   

  29. #29

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: My Potions are too strong for you Traveller. Cairo Hue Shift?

    Ok, here's my working code for a Cairo Surface shift.
    Just feed it any surface and give it a 0 to 255 hue shift amount.

    Name:  Yep Thats a potion.jpg
Views: 692
Size:  41.8 KB

    BUT: Stick in this guy's modules before you do: https://www.vbforums.com/showthread....RGB-conversion
    THANK YOU BEN321 from Jan 19th, 2015, 08:13 PM. Your excellent quality service has been recognized!

    Code:
    Sub Hue_Shift_Me(My_Surface As cCairoContext, ByVal Hue_Shift_Amount As Single)
    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    '   Hue Shift a Surface
    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    'This sub hue shifts an surface by a set amount. Note Hue is 0 to 255 max.
    Dim Pixel_Height As Long 'Height of the surface
    Dim Pixel_Width As Long 'Width of the surface
    Pixel_Height = My_Surface.Surface.Height 'Write down their sizes
    Pixel_Width = My_Surface.Surface.Width
    Dim My_Connection() As Byte 'This is the bound array connection to the surface so we can extract and write pixel data
    Dim C As Integer 'Counter
    Dim D As Integer 'Counter
    Dim Hue As Byte
    Dim Value As Byte
    Dim Saturation As Byte
    Dim Red As Byte: Dim Green As Byte: Dim Blue As Byte 'Our wanted pixel colours
    Dim Trim_Amount As Integer
    '[BIND SURFACE TO OPERATIONL ARRAY]
    My_Surface.Surface.BindToArray My_Connection 'Conenct the surface for input and output
    'Let's scan through all the pixels to extract R, G & B values
    For D = 0 To (Pixel_Height - 1) 'To the full image height
        For C = 0 To (Pixel_Width - 1) * 4 Step 4 'To the full image width. In byte form, we need to skip over some data (alpha)
            Blue = My_Connection(C + 0, D)
            Green = My_Connection(C + 1, D)
            Red = My_Connection(C + 2, D)
            'Now that we have R,G,B, we can convert that to a hue
            'If it's all zero's neglect it
            If Blue <> 0 Or Red <> 0 Or Green <> 0 Then
                'Call Colour_Shift(Red, Green, Blue, Hue_Shift_Amount)
                Call RGBtoHSV(Red, Green, Blue, Hue, Saturation, Value)
                'Add the hue shift
                If (Hue + Hue_Shift_Amount) > 255 Then 'If over, use the excess as the new value
                    Trim_Amount = Hue + Hue_Shift_Amount - 255
                    Hue = Trim_Amount
                Else
                    Hue = Hue + Hue_Shift_Amount 'Standard add which doesn't go over 255
                End If
                Call HSVtoRGB(Hue, Saturation, Value, Red, Green, Blue)
                'Over write the hue shift
                My_Connection(C + 0, D) = Blue
                My_Connection(C + 1, D) = Green
                My_Connection(C + 2, D) = Red
            End If
        Next C
    Next D
    My_Surface.Surface.ReleaseArray My_Connection 'Release the array
    End Sub
    And now the Methstar has been destroyed!

    Name:  Methstar Gone.jpg
Views: 688
Size:  5.8 KB

    Ok, will update with pictures when I gets me arts done.

  30. #30

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Name:  Fancy a little tiddly wink.jpg
Views: 715
Size:  60.2 KB
    Ahhhhh it's working now. Fancy a little tiddly wink there guvenar!

    I tweaked the saturation in the code too. You just overwrite the Saturation value to a new random one.

    Name:  index.png
Views: 692
Size:  8.5 KB

  31. #31
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    FWIW, here is my take at HSV-Routines (best placed in a *.bas Module):
    Code:
    Public Sub RGB2HSV(ByVal R As Byte, ByVal G As Byte, ByVal B As Byte, H As Long, S As Single, V As Single)
      If G > R Then H = G - R:     V = G Else H = R - G: V = R
      If B > V Then H = B - V + H: V = B Else If V - B > H Then H = V - B
      If V = 0 Then S = 0 Else S = H / V: V = V / 255
     
      Select Case CByte(V * 255) 'return H Between 0 and 360 (S and V between 0 and 1)
          Case R: If H Then H = 60 * ((0 + G - B) / H + 0): If H < 0 Then H = H + 360
          Case G: If H Then H = 60 * ((0 + B - R) / H + 2)
          Case B: If H Then H = 60 * ((0 + R - G) / H + 4)
      End Select
    End Sub
    
    Public Sub HSV2RGB(ByVal H As Long, ByVal S As Single, ByVal V As Single, R As Byte, G As Byte, B As Byte)
      Dim i As Long, X As Long
      For i = 1 To 5 Step 2
          X = (H + i * 60 + 360000) Mod 360: If X >= 180 Then X = 240 - X
          If X < 0 Then X = 0 Else If X > 60 Then X = 60
          
          If i = 5 Then R = V * (1 - S * X / 60) * 255
          If i = 3 Then G = V * (1 - S * X / 60) * 255
          If i = 1 Then B = V * (1 - S * X / 60) * 255
      Next
    End Sub
    The above pair operates (native-compiled) about factor 20 faster than what Niya has produced.

    And here's a function, which does Hue-Rotation (also to be placed in a *.bas):
    Code:
    Public Function HueRotate(Src As cCairoSurface, ByVal HueAngle_PlusMinus360 As Long, _
                              Optional ByVal SatIntervalMin As Single, Optional ByVal SatIntervalMax As Single = 1, _
                              Optional ByVal LumIntervalMin As Single, Optional ByVal LumIntervalMax As Single = 1) As cCairoSurface
      
      Dim P() As Byte, X As Long, Y As Long, H As Long, S As Single, V As Single
      Set HueRotate = Src.CreateSimilar(, , , True) 'make a copy of the source
      
      Cairo.DeMultiplyAlpha HueRotate.DataPtr, HueRotate.Stride * HueRotate.Height
      HueRotate.BindToArray P
          For Y = 0 To UBound(P, 2): For X = 0 To UBound(P, 1) Step 4 '<- notice Step4 (Byte-Order in P is "BGRA")
              RGB2HSV P(X + 2, Y), P(X + 1, Y), P(X + 0, Y), H, S, V
      
              If S >= SatIntervalMin And S <= SatIntervalMax Then
                 If V >= LumIntervalMin And V <= LumIntervalMax Then
                    HSV2RGB H + HueAngle_PlusMinus360, S, V, P(X + 2, Y), P(X + 1, Y), P(X + 0, Y)
                 End If
              End If
          Next X, Y
      HueRotate.ReleaseArray P
      Cairo.PreMultiplyAlpha HueRotate.DataPtr, HueRotate.Stride * HueRotate.Height
    End Function
    Please note the enclosing of the Pixel-Loop between "De- and Pre-Multiply-Alpha" calls (on the Result-Surface).
    It's important to expand the RGB-Values to their "full-range" first (before doing HSL or HSV manipulations) -
    ...the final PreMultiply will ensure proper Alpha-Channel-corresponding RGB-Values before routine-exit.

    Also note the Optional Filter-Params for Saturation and Luminance (if you leave them out, you will have a "Standard-Hue-Shift").

    Ok, Form-Test-Code for all that:
    Code:
    Option Explicit
    
    Private Src As cCairoSurface
    
    Private Sub Form_Load()
        Caption = "Press a MouseButton, and Move the Mouse"
        Set Src = Cairo.ImageList.AddImage("", App.Path & "\potion_orig.png", 128, 128)
        Set Picture = Src.Picture
    End Sub
     
    Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
      If Button = 0 Then Exit Sub 'do nothing, until the User presses a MouseKey whilst moving
      Dim HueAngle As Long, Result As cCairoSurface
          HueAngle = (X + Y) / (ScaleWidth + ScaleHeight) * 360
          Caption = "Current HueAngle: " & HueAngle & "°"
          New_c.Timing True
             Set Result = HueRotate(Src, HueAngle, 0.75, 1) '<- the Saturation-FilterInterval is optional
          Caption = Caption & New_c.Timing
          Result.DrawToDC hDC
    End Sub
    HTH

    Olaf

  32. #32
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Yea, go with Olaf's version. It's way better than what I posted.

    However, I'd be curious to know if what he posted above works for you. The reason I ask is because based on what you posted about the results you expected, there is something else I wanted to try.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  33. #33
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Here is a quick and dirty test that uses GDI32. No GDI+, no Cairo, no add-in libraries at all.

    It seems to be close to what we're talking about here. The main limitation is that it doesn't have as "Save as PNG" option for tweaked images, which would require the use of some library (GDi+, etc.) since GDI32 has no PNG encoder I'm aware of. Another limitation is that it requires Windows Vista or later: it can't run on Altair Basic or Windows XP.

    Bonus: It copes with High and even Per Monitor DPI on Windows 10 (version 1703 Creator's Update) or later. No coding hoops jumped through, it relies on the appcompat option "GDI Scaling."


    Easy to test, unzip the archive. Then copy the two images above into the Project folder ("Bottle Yellow Green.png" and "Bottle Light.png"). Runs in the IDE, or better as a compiled EXE.

    Probably a bit crude, I just wanted to see what I could get quickly.
    Attached Files Attached Files

  34. #34

    Thread Starter
    Hyperactive Member -Corso->'s Avatar
    Join Date
    Oct 2021
    Posts
    379

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Oh nice Job Dilettante. That works nicely! There's a man who knows his potion bottles. And a swift drink to you!

    Olaf, did something go a bit funny? The little leather bits didn't alter and there was a brown spot on the glass.
    Name:  Olafs Hueshifter.jpg
Views: 706
Size:  42.9 KB

    And now the fun begins...
    Name:  Taverny.jpg
Views: 699
Size:  53.1 KB
    More alcohol than a Dwarven Brewery coming up.

  35. #35
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by dilettante View Post
    Here is a quick and dirty test that uses GDI32. No GDI+, no Cairo, no add-in libraries at all.

    It seems to be close to what we're talking about here. The main limitation is that it doesn't have as "Save as PNG" option for tweaked images, which would require the use of some library (GDi+, etc.) since GDI32 has no PNG encoder I'm aware of. Another limitation is that it requires Windows Vista or later: it can't run on Altair Basic or Windows XP.

    Bonus: It copes with High and even Per Monitor DPI on Windows 10 (version 1703 Creator's Update) or later. No coding hoops jumped through, it relies on the appcompat option "GDI Scaling."


    Easy to test, unzip the archive. Then copy the two images above into the Project folder ("Bottle Yellow Green.png" and "Bottle Light.png"). Runs in the IDE, or better as a compiled EXE.

    Probably a bit crude, I just wanted to see what I could get quickly.
    I can't get your sample to work on my PC:-
    Code:
            Case vbString
                F = FreeFile(0)
                Open PngData For Binary Access Read As #F
                ReDim PngBytes(LOF(F) - 1)
                Get #F, , PngBytes
                Close #F
    It crashes at the line in red with a "subscript out of range" error. I checked the value of LOF(F) and it returned 0 which suggested to me that it wasn't finding the file. I attempted a fix by prepending App.Path but for some reason it still doesn't work. LOF(F) still returns 0 which means it's still not finding the file. My VB6 is still rusty in many areas so I'm wondering if it has anything to do with the actual path of the image:-
    Code:
    D:\New VB6 Stuff\AAA Experiments with HSB, RGB HSL etc\GDI Potion Blender\Bottle Yellow Green.png
    I'm wondering if VB6's open statement is having trouble with that path somehow.

    EDIT:

    NVM. I think I found the problem.

    EDIT:

    Yea, I found the problem. The PNG file was corrupted somehow. It was 0 bytes in length. I just had to re-download the image. The program works now.
    Last edited by Niya; Jun 5th, 2022 at 05:24 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  36. #36
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by -Corso-> View Post
    There's a man who knows his potion bottles.
    Well, thanks. But if you saw the ones I tried to draw myself you might die from laughing or crying.

    No artist here! And I was working with stone knives and bearskins (MS Paint, MS Paint 3D, IrfanView, and some quickly-hacked together WIA scripts).

  37. #37
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Quote Originally Posted by Niya View Post
    I'm wondering if VB6's open statement is having trouble with that path somehow.
    Could be. A quick workaround might be to load the data via ADODB.Stream instead, since it accepts a Unicode file path.


    Ahh, good to see you resolved the issue.

  38. #38
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Looking at Dilettante's program, I'm starting to think that HSL would have been a better colour space than HSB. My PixelPainter app also uses HSL and it produces similar results. The only difference is that Dilettante's code somehow avoids rotating the grays at the bottle cork, the logo on the bottle and the grey lighting to the left-bottom of the bottle. PixelPainter on the other hand would rotate everything. However, in my app, specific pixels could be selected and when I select only the contents of the bottle, avoiding the grey areas, it produces the same output as Dilettante's program. Long story short, HSL seems to produce better results than HSB.

    @Dilettante.

    I also notice in your code, you only allow hue rotations of 240 degrees. Why not the full 360?

    Also, how does your code avoid rotating the greys? If I select all pixels in my pixel painter app, this is the result:-


    As you can see, everything is shifted yet in your code I can't readily tell how the greys are being avoided without manual intervention. What's the insight?
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  39. #39
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    Those ShLwAPI calls only use 0-240 for the 3 elements even though 16-bit WORD arguments are used. Weird, hmm?


    I used a hack for those oddball colors. If the "adjusted" color is black but the original color was not black... I restored the original color of that pixel and moved on to premultiply.

    It seems that the ShLwAPI calls "blackhole" any colors not within their colorspace, i.e. return 0 without any other error indication.

  40. #40
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [RESOLVED] My Potions are too strong for you Traveller. Cairo Hue Shift?

    I see I have some leftover junk from early testing too. For example:

    Code:
    Private Sub Draw()
        Dim ScaleBy As Long
        Dim DrawW As Long
        Dim DrawH As Long
    
    Two variables are declared but no longer used and can be deleted.

    There are probably a few more goofs and artifacts of playing, and little attempt was made at optimization.


    The key to being "safe for GDI Scaling" is to avoid DIBs and use DDBs wherever possible. DIBs do not get automagically scaled.


    Found another gaffe from tinkering:

    Code:
        For I = 0 To BitBytesCount - 1 Step 4
            BitBytes(I + 3) = BitBytes(I + 3)
            Alpha = BitBytes(I + 3)
            If Alpha = 0 Then
                BitBytes(I) = 0
                BitBytes(I + 1) = 0
                BitBytes(I + 2) = 0
            Else
    Now it's getting embarrassing. But that one came from an early experiement where there were two arrays thee.
    Last edited by dilettante; Jun 5th, 2022 at 06:10 PM.

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