Ooops
February 27, 2021, 04:19:37 AM

Author Topic: [bb] Monochrome by xlsior [ 1+ years ago ]  (Read 513 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Monochrome by xlsior [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : Monochrome
Author : xlsior
Posted : 1+ years ago

Description : Converts a color image to greyscale

Code :
Code: BlitzBasic
  1. ;
  2. ; Monochrome -- A function that converts the contents backbuffer() to greyscale.
  3. ; 11/23/2003, by Marc van den Dikkenberg / xlsior
  4. ;
  5. ; Usage: monochrome(perct#)
  6. ;                perct# is the level of the effect, in percentages.
  7. ;                0 means no change, while 100 is pure greyscales.
  8. ;
  9. ; Note: The fade itself is probably to slow to be useful,
  10. ; and has been included for educational purposes only.
  11. ;
  12.  
  13. Graphics 640,480,16,2
  14. SetBuffer BackBuffer()
  15.  
  16. gfx$=LoadImage("x:monkey6.jpg")
  17. DrawImage gfx$,0,0
  18. Flip
  19. WaitKey()
  20.  
  21. For perct=10 To 100 Step 10
  22.         DrawImage gfx$,0,0
  23.         Monochrome(perct)
  24.         Flip
  25. Next
  26.  
  27. fntArial=LoadFont("Arial",24,True,False,False)
  28. SetFont fntarial
  29. Color 255,128,0
  30. Rect 200,220,240,40
  31. Color 255,255,255
  32. Text 260,230,"Intermission"
  33. FreeFont fntarial
  34. Flip
  35. WaitKey()
  36.  
  37. For perct=100 To 10 Step -10
  38.         DrawImage gfx$,0,0
  39.         Monochrome(perct)
  40.         Flip
  41. Next
  42.  
  43. WaitKey()
  44. End
  45.  
  46.  
  47. Function Monochrome(perct#)
  48.         SetBuffer BackBuffer()
  49.         LockBuffer
  50.         For y=0 To 479
  51.                 For x=0 To 639
  52.                         temp1=ReadPixel(x,y)
  53.                        
  54.                         orgb=(temp1 And $FF)
  55.                         orgg=(temp1 And $FF00) Shr 8
  56.                         orgr=(temp1 And $FF0000) Shr 16
  57.                         desb=((orgr*0.299)+(orgg*0.587)+(orgb*0.114))
  58.                 desr=orgr*(1-(perct#/100))+desb*(perct#/100)
  59.                 desg=orgg*(1-(perct#/100))+desb*(perct#/100)
  60.                         desb=orgb*(1-(perct#/100))+desb*(perct#/100)
  61.  
  62.                         WritePixel x,y,desb+(desg Shl 8)+(desr Shl 16)
  63.                 Next
  64.         Next
  65.         UnlockBuffer
  66. End Function


Comments :


MathyDude(Posted 1+ years ago)

 Maybe if you replace[bbcode]         temp1=ReadPixel(x,y)                  orgb=(temp1 And $FF)         orgg=(temp1 And $FF00) Shr 8         orgr=(temp1 And $FF0000) Shr 16         desb=((orgr*0.299)+(orgg*0.587)+(orgb*0.114))       desr=orgr*(1-(perct#/100))+desb*(perct#/100)       desg=orgg*(1-(perct#/100))+desb*(perct#/100)          desb=orgb*(1-(perct#/100))+desb*(perct#/100)          WritePixel x,y,desb+(desg Shl 8)+(desr Shl 16)[/bbcode]with[bbcode]         temp1=ReadPixelfast(x,y)                  orgb=(temp1 And $FF)         orgg=(temp1 And $FF00) Shr 8         orgr=(temp1 And $FF0000) Shr 16         desb=((orgr*0.299)+(orgg*0.587)+(orgb*0.114))       desr=orgr*(1-(perct#/100))+desb*(perct#/100)       desg=orgg*(1-(perct#/100))+desb*(perct#/100)          desb=orgb*(1-(perct#/100))+desb*(perct#/100)          WritePixelfast x,y,desb+(desg Shl 8)+(desr Shl 16)[/bbcode]then it would go faster!


virtlands(Posted 1+ years ago)

 I just tried your progam.That's an interesting grey-scale algorithm: Gray = (Red * 0.299 + Green * 0.587 + Blue * 0.114)I found this website that has lots of free image effect and filters algorithms.<a href="http://www.tannerhelland.com/programming-directory/" target="_blank">http://www.tannerhelland.com/programming-directory/[/url]


xlsior(Posted 1+ years ago)

 <div class="quote"> That's an interesting grey-scale algorithm: Gray = (Red * 0.299 + Green * 0.587 + Blue * 0.114) </div>It's the proper formula for luminosity -- Since the human eye has different sensitivities to light in the red/green/blue ranges of the spectrum, you can't just average them out but have to use the weighted valued for the apparent luminosity to remain the same.More info: <a href="http://en.wikipedia.org/wiki/Luma_(video)" target="_blank">http://en.wikipedia.org/wiki/Luma_(video)[/url](There's other things that make use of those facts: More than half of the information you observe comes from the green part of the spectrum, less than a third from the red, and barely 1/9th from the blue. JPEG image compression makes use of that fact, and uses chroma sub-sampling as part of the compression algorithm.It seperates the source image into its discrete red, green and blue layers, and compresses them individually. It uses a conservative compression on the green channel, and very agressive compression on the blue channel to get you the smallest file size with the least visual impact caused by the lossy (lost) information.<a href="http://photo.net/learn/jpeg/" target="_blank">http://photo.net/learn/jpeg/[/url]<div class="quote"> Here's a wild idea of mine that may be faster for doing a massive grey-scale conversion on 24-bit images. >>Since there are 16777216 colors (in 24bits), then pre-compute the grey scales of all 16777216 colors, and store it in a massive array. </div>You know, never really considered doing that, but you're right -- the amount of data is not that big, and it would safe a lot of floating point divisions. could be worth checking out.(Of course, I posted the source above almost a decade ago. In blitzmax, there's much faster ways of accomplishing this feature in real-time, using various blitzmax modules that make use of either shaders or other features of modern 3D accelerator cards)


virtlands(Posted 1+ years ago)

 O.K.  I see now.  Just had an idea for optimizing it, will be back in a while...I just figured that there is a drawback with pre-computing all grey-codes of all 16777216 colors (for 1 photo), because most photos, (PNG, JPG, etc.) only use a small fraction of the 16777216 colors.


xlsior(Posted 1+ years ago)

 <div class="quote"> I just figured that there is a drawback with pre-computing all grey-codes of all 16777216 colors (for 1 photo), because most photos, (PNG, JPG, etc.) only use a small fraction of the 16777216 colors.  </div>Easiest way of storing it would probably be a straight (255,255,255) array.  That'd be 16 MB as a byte array, or 64MB as an integer array (which will probably be faster)


virtlands(Posted 1+ years ago)

 I had some fun trying to optimize your grey code ideas for speed.  I had this idea of dividing up an image into equal tasks spread across computer cores (=threading). The threads would run parallel to each other, which would make the program run fast.Each thread (or core) would devote itself to unique lines of the image, in an interlaced sort of way.My regular optimized code (Version A) worked fine,but my experiment with threading (Version B) didn't work at all.  I have a hunch that the WritePixel command cannot be used in threads, and that's why it won't work.If you want to see the (wip) codes you can, here are both Versions, A & B:<a href="http://tinyurl.com/d7kcxhq" target="_blank">http://tinyurl.com/d7kcxhq[/url]You'll also need the FastPointer.DLL + FreeImage.DLL + .DECLS <a href="http://tinyurl.com/czrvopm" target="_blank">http://tinyurl.com/czrvopm[/url]My great idea was the grey-array, which used a giant array of precomputed greys:<div class="quote"> ;;  Grey values are computed as they occur and stored in the huge  "greycode()"  array.;;  For quickness, this does not compute the entire 16777216  collection,;;  but only those that exist in the specified image.;;  Also, greycodes that already exist do not need to be recalculated...;;Function GreyArray(i.it)     Local imW_ = iW -1    Local imH_ = iH  -1      Local fi = ifi      Local save_buf, im_buf,  R,G,B     save_buf = GraphicsBuffer()  ; save the currently active buffer     im_buf =  ImageBuffer( iim )     SetBuffer im_buf  ;; set the buffer to the image buffer     LockBuffer      For y=0 To imH_     For x=0 To imW_                  pixel = ReadPixelFast(x,y) And $00FFFFFF  ;; remove the "alpha" from an image.                  If greycode(pixel)  ;; If duplicate pixels occur, then no need to recompute.                  Else                           R = (pixel And $FF0000) Shr 16                          G  =(pixel And $00FF00) Shr 8                          B  =(pixel) And $FF                          greycode(pixel) = (R*0.299)+(G*0.587)+(B*0.114)                    End If         Next      Next      UnlockBuffer       SetBuffer save_bufEnd Function  </div>;--------------------------------------------------I'm not sure, but I think the 2 arraysDIM A(255,255,255)DIM B(16777216)both take the same bytes, which is 67108864  = 68 MBbecause multidimensional arrays in B3D take LONGS.A Long = an INT = 4 bytes = 32 bitties.  You can perhaps store the data in a bank instead, and use 3 bytes per pixel, (getting rid of the high-byte)b = createbank(16777216*3) ; taking approx 50MBThe drawback would be that retrieval of each 'grey' would be more complex.


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal