forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Unpacking RGB colours

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
silicondale



Joined: 15 Mar 2007
Posts: 243
Location: Matlock, Derbyshire, UK

PostPosted: Wed Mar 05, 2014 7:15 pm    Post subject: Unpacking RGB colours Reply with quote

Is there any library subroutine to unpack the R, G, B components of an RGB colour? This would be the inverse of the RGB@ function. I'm sure it's not too difficult to write, but I don't want to reinvent it if already available.
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7923
Location: Salford, UK

PostPosted: Wed Mar 05, 2014 7:46 pm    Post subject: Reply with quote

I don't think there is.

It will be something like the following but I have not tested this...

Code:
   red   = IAND(rgb, 255) 
   green = IAND(ISHFT(rgb,-8), 255)
   blue  = IAND(ISHFT(rgb,-16), 255) 
Back to top
View user's profile Send private message AIM Address
silicondale



Joined: 15 Mar 2007
Posts: 243
Location: Matlock, Derbyshire, UK

PostPosted: Wed Mar 05, 2014 7:52 pm    Post subject: Reply with quote

That was quick! So the answer is no, but you've given me more than half the wheel to work with -- many thanks!
-Steve
Back to top
View user's profile Send private message Visit poster's website
jalih



Joined: 30 Jul 2012
Posts: 196

PostPosted: Wed Mar 05, 2014 9:21 pm    Post subject: Reply with quote

How about something like:
Code:

program test
  integer*4 :: r, g, b
  integer*4 :: i

  i = Z'00FF0000'_3
 
  call INT2RGB(i, r, g, b)

  write(*,*) 'integer :', i
  write(*,*) 'R:', r
  write(*,*) 'G:', g
  write(*,*) 'B:', b
 
  contains
     subroutine INT2RGB(int, r, g, b)
      integer*4 :: int
      integer*4 :: r, g, b

      type rgb
        union
          map
            integer*1 :: b, g, r, a
          end map
          map
            integer*4 :: c
          end map
        end union
      end type rgb

      type(rgb) :: c
     
      c%c = int

      r = IAND(c%r, 255)
      g = IAND(c%g, 255)
      b = IAND(c%b, 255)

    end subroutine INT2RGB
   

end program test
Back to top
View user's profile Send private message
silicondale



Joined: 15 Mar 2007
Posts: 243
Location: Matlock, Derbyshire, UK

PostPosted: Wed Mar 05, 2014 9:56 pm    Post subject: Reply with quote

Many thanks, Jalih- brilliant as always !!
------------------
(edit 06/03)
Tested last night. Works fine, but I think the order it gives is b g r not r g b. Would be useful to have this as a standard library subroutine.


Last edited by silicondale on Thu Mar 06, 2014 9:22 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Mar 06, 2014 8:56 am    Post subject: Reply with quote

You can also use transfer intrinsic with an integer*1 RGB(4), being careful to check the order. Sign is a problem with integer*1. Is there a byte type ?

Not sure that map and union exist in F95 ?

John
Back to top
View user's profile Send private message
jalih



Joined: 30 Jul 2012
Posts: 196

PostPosted: Thu Mar 06, 2014 11:35 am    Post subject: Re: Reply with quote

silicondale wrote:
Works fine, but I think the order it gives is b g r not r g b.

That's possible, I used some web based RGB to integer calculator results as a reference. Just change the order of the integer*1 variables inside the union.

JohnCampbell wrote:

Not sure that map and union exist in F95 ?

You are right, the map and union constructs are language extensions. I think it's a really handy feature.
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Thu Mar 06, 2014 1:50 pm    Post subject: Reply with quote

I hope that Paul will incorporate useful routines like this in the standard library in due course.

I've struggled over a related issue, but gave up (it's a very standard response of mine to a problem!) and that is automatically reducing the colour intensity while keeping recognisably the same colour. The application is basically printing an image which looks best on the screen in saturated colours. If you go to print that you get (on my inkjet) soggy areas that soak the intense colour areas and stretch all but the most expensive 'art' papers or (on my laser) make it look like the paper is covered in a layer of gloss paint that you could peel off. There's no doubt in my mind that printed images look better with less saturated colour. (Line drawings work better with saturated colours of course. I'm talking about the ones that have large areas of solid colour).

It became very obvious to me that just increasing or decreasing the r,g,b values while keeping them in the same ratio doesn't work (except for grey, when r=g=b, and even then, the perception of grey intensity is non-linear). My printers seem to work in CMYK, but the drivers accept RGB, so someone must know how to map from one to the other, but I suspect that hue, saturation, lightness is probably the easiest way to go.

Thus automatically flattening the colour would involve taking rgb, convert to hsl, tone down saturation (? - with or without increasing lightness?) and re-map to rgb for printing.

If my application only featured a few standard colours I suppose I could keep a table of the rgb values for several stages of lightening. My present solution is to encourage the user to make appropriate colour choices ab initio.

Eddie
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7923
Location: Salford, UK

PostPosted: Thu Mar 06, 2014 2:33 pm    Post subject: Reply with quote

MAP and UNION are available in FTN95 but they may not be documented.
Back to top
View user's profile Send private message AIM Address
Wilfried Linder



Joined: 14 Nov 2007
Posts: 314
Location: Düsseldorf, Germany

PostPosted: Thu Mar 06, 2014 6:07 pm    Post subject: Reply with quote

If irgb is the RGB@ colour value and ired, igre and iblu are the 8-bit colour values, then

Code:
      ired = iand(lobyte(loword(irgb)),255)
      igre = iand(hibyte(loword(irgb)),255)
      iblu = hiword(irgb)

can be used for instance.

Regards - Wilfried
Back to top
View user's profile Send private message
silicondale



Joined: 15 Mar 2007
Posts: 243
Location: Matlock, Derbyshire, UK

PostPosted: Thu Mar 06, 2014 6:28 pm    Post subject: Reply with quote

Eddie - I think this may help...
http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/

Code:

      integer r,g,b,h,l,s
      real*4 r1,g1,b1,hue,lum,sat,cmax,cmin

      r1 = float(r)/255.0
      g1 = float(g)/255.0
      b1 = float(b)/255.0

      cmin = amin1(r1,g1,b1)
      cmax = amax1(r1,g1,b1)
      if (cmin.eq.cmax) then
        sat = 0.0
        hue = 0.0
      else
        lum1 = int((cmin+cmax)*0.5)

        if (lum.lt.0.5) then
          sat = (cmax-cmin)/(cmax+cmin)
        else
          sat = (cmax-cmin)/(2.0-cmax-cmin)
        end if

        if (cmax.eq.r1) then
          hue = (g1-b1)/(cmax-cmin)
        else if (cmax.eq.g1) then
          hue = 2.0 + (b1-r1)/cmax-cmin)
        else if (cmax.eq.b1) then
          hue = 4.0 + (r1-g1)/(cmax-cmin)
        end if

        hue = hue * 60.0
        if (hue.lt.0.0) hue = hue + 360.0
        if (hue.gt.360.0) hue = hue - 360.0

      end if
      h = ifix (hue)
      l = ifix (lum)
      s = ifix (sat) 


First stab at coding it. The website gives a back conversion to RGB as well, so you can get what you want - a toned-down RGB. Come to think of it, this would be jolly useful for 'greyed' buttons where you have a coloured button.

- Steve
Back to top
View user's profile Send private message Visit poster's website
jalih



Joined: 30 Jul 2012
Posts: 196

PostPosted: Thu Mar 06, 2014 8:33 pm    Post subject: Reply with quote

Here is a small utility for converting HSV to RGB. MiniBASIC source is included and should port easily to FTN95 if needed.
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Thu Mar 06, 2014 11:46 pm    Post subject: Reply with quote

Wow,

Two answers straightaway! I'll need to experiment with how much lighter is optimum, but thanks.

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Fri Mar 07, 2014 4:04 am    Post subject: Reply with quote

I think just using ishift is most straightforward.
I could not get it to break !
Code:
include <clearwin.ins>
!
   real*4    x(3)
   integer*4 red_i, green_i, blue_i, rgb_i,  red_o, green_o, blue_o, i, error
!
  do i = 1,10000000
!
! get an RGB Value
   call random_number ( x )
!
   red_i   = int ( x(1)*256. )
   green_i = int ( x(2)*256. )
   blue_i  = int ( x(3)*256. )
!
   rgb_i   = rgb@ ( red_i, green_i, blue_i )
!
   call from_rgb ( rgb_i, red_o, green_o, blue_o)
!
   if (i > 1) then
    error = abs (red_o  -red_i) + abs (green_o-green_i) + abs (blue_o -blue_i)
    if (error == 0) CYCLE
    write (*,*) 'ERROR : CHECK THE CONVERSION', I
   end if
!
   write (*,*) ' '
   write (*,*) 'RGB value is',rgb_i
   write (*,*) ' red is   :', red_i,   red_o,   red_o  -red_i
   write (*,*) ' green is :', green_i, green_o, green_o-green_i
   write (*,*) ' blue is  :', blue_i,  blue_o,  blue_o -blue_i
  end do
  write (*,*) i-1,' tests'
!
end

   subroutine from_rgb ( rgb_i, red_o, green_o, blue_o)
   integer*4 rgb_i,  red_o, green_o, blue_o

   red_o   = IAND (rgb_i, 255) 
   green_o = IAND (ISHFT(rgb_i,-8), 255)
   blue_o  = IAND (ISHFT(rgb_i,-16), 255) 

end subroutine from_rgb
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group