January 26, 2021, 06:33:22 AM

Author Topic: [bb] Image Processing Functions by Myke-P [ 1+ years ago ]  (Read 409 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Image Processing Functions by Myke-P [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : Image Processing Functions
Author : Myke-P
Posted : 1+ years ago

Description : Image Processing Functions: More to come as they're completed. Next time 'round I'll have over commented these and the successive jobbies for all you Image Processing junkies! :)

Oh.. You'll need to provide a picture (currently called "TestIn.bmp" in the current folder) for these to work!

Probably not fast enough for real-time on-screen effects (sadly) but feel free to optimize them. Aside from that, feel free to use them, expand upon them and generally enjoy them in any way you see fit! If you do something similar or even better (can't be hard!) then share them with us too!


Code :
Code: BlitzBasic
  1. ;Image Functions by Myke-P 2001
  2. ;various PixelFast functions that do funky things to images.
  3. ;Thanks to John C and Rob Cummings for their invaluable help.
  4.  
  5. AppTitle "Image Functions by Myke-P 2001"
  6. Graphics 640,480,0,2
  7. Global sourceimage = LoadImage("TestIn.bmp")
  8. Global destinimage
  9. Dim floydsarray#(0,0)
  10.  
  11. starttime = MilliSecs()
  12.  
  13. ;uncomment one at a time, as appropriate, for a demo,
  14. ;otherwise you'll get the dreaded "illegal memory address"! :)
  15.  
  16. ;destinimage = Image_Greyscale(sourceimage)
  17. ;destinimage = Image_Pixelate(sourceimage,5,5,2)
  18. ;destinimage = Image_Scanline(sourceimage,100,1)
  19. ;destinimage = Image_Colourise(sourceimage,255,0,255,1)
  20. ;destinimage = Image_Brightness(sourceimage,80,50)
  21. ;destinimage = Image_Negative(sourceimage)
  22. ;destinimage = Image_FloydDither(sourceimage)
  23.  
  24. endtime = MilliSecs()
  25. SaveBuffer (ImageBuffer(destinimage),"TestOut.bmp")
  26. SetBuffer FrontBuffer()
  27. DrawBlock destinimage,0,20
  28. DrawBlock sourceimage,ImageWidth(destinimage),20
  29. Text 0,0,"That took: " + (endtime-starttime) + " millisecs."
  30. WaitKey()
  31. End
  32.  
  33. ;IMAGE_GREYSCALE
  34. ;Turns an image into hues of Grey.
  35. ;
  36. ;source = source image handle
  37. Function Image_Greyscale(source)
  38. currbuff = GraphicsBuffer()
  39. destin = CopyImage (source)
  40. SetBuffer ImageBuffer(destin)
  41. LockBuffer()
  42. For i = 0 To ImageWidth(destin)-1
  43.         For j = 0 To ImageHeight(destin)-1
  44.                 col = ReadPixelFast(i,j) And $FFFFFF
  45.                 redlevel = (col Shr 16) And $FF
  46.                 greenlevel = (col Shr 8) And $FF
  47.                 bluelevel = col And $FF
  48.                 greylevel = Int(0.298039215 * redlevel) + Int(0.588235293 * greenlevel) + Int(0.109803921 * bluelevel)
  49.                 argb = (greylevel Or (greylevel Shl 8) Or (greylevel Shl 16) Or (255 Shl 24))
  50.                 WritePixelFast i,j,argb
  51.         Next
  52. Next
  53. UnlockBuffer()
  54. SetBuffer currbuff
  55. Return destin
  56. End Function
  57.  
  58. ;IMAGE_PIXELATE
  59. ;Turns an image into chunky pixels (size of your choice)
  60. ;
  61. ;source = source image handle
  62. ;x = width of pixelation
  63. ;y = height of pixelation
  64. ;option = 1: averaging off (default), 2: averaging on
  65. Function Image_Pixelate(source,x,y,option)
  66. currbuff = GraphicsBuffer()
  67. If option <> 1 And option <> 2 Then
  68.         option = 1
  69. End If
  70. destin = CopyImage(source)
  71. SetBuffer ImageBuffer(destin)
  72. LockBuffer()
  73. Select option
  74.         Case 1
  75.                 i = 0
  76.                 While i <= ImageWidth(destin)-1
  77.                         j = 0
  78.                         While j <= ImageHeight(destin)-1
  79.                                 col = ReadPixelFast(i,j) And $FFFFFF
  80.                                 redlevel = (col Shr 16) And $FF
  81.                                 greenlevel = (col Shr 8) And $FF
  82.                                 bluelevel = col And $FF
  83.                                 argb = (bluelevel Or (greenlevel Shl 8) Or (redlevel Shl 16) Or (255 Shl 24))
  84.                                 For k = 0 To x-1
  85.                                         For l = 0 To y-1
  86.                                                 If ((i+k) < ImageWidth(destin)) And ((j+l) < ImageHeight(destin)) Then
  87.                                                         WritePixelFast (i+k),(j+l),argb
  88.                                                 End If
  89.                                         Next
  90.                                 Next
  91.                                 j = j + y
  92.                         Wend
  93.                         i = i + x
  94.                 Wend
  95.         Case 2
  96.                 i = 0
  97.                 While i <= ImageWidth(destin)-1
  98.                         j = 0
  99.                         While j <= ImageHeight(destin)-1
  100.                                 redlevel = 0
  101.                                 greenlevel = 0
  102.                                 bluelevel = 0
  103.                                 numpixels = 0
  104.                                 ;pass one - add all the r, g and b values together
  105.                                 For k = 0 To x-1
  106.                                         For l = 0 To y-1
  107.                                                 If ((i+k) < ImageWidth(destin)) And ((j+l) < ImageHeight(destin)) Then
  108.                                                         col = ReadPixelFast(i+k,j+l) And $FFFFFF
  109.                                                         redlevel = redlevel + ((col Shr 16) And $FF)
  110.                                                         greenlevel = greenlevel + ((col Shr 8) And $FF)
  111.                                                         bluelevel = bluelevel + (col And $FF)
  112.                                                         numpixels = numpixels + 1
  113.                                                 End If
  114.                                         Next
  115.                                 Next
  116.                                 ;work out the average r, g and b values by deviding by the number of counted pixels in the x*y block
  117.                                 redlevel = Int(redlevel/numpixels)
  118.                                 greenlevel = Int(greenlevel/numpixels)
  119.                                 bluelevel = Int(bluelevel/numpixels)
  120.                                 argb = (bluelevel Or (greenlevel Shl 8) Or (redlevel Shl 16) Or (255 Shl 24))
  121.                                 ;pass two - draw pixels of that colour
  122.                                 For k = 0 To x-1
  123.                                         For l = 0 To y-1
  124.                                                 If ((i+k) < ImageWidth(destin)) And ((j+l) < ImageHeight(destin)) Then
  125.                                                         WritePixelFast (i+k),(j+l),argb
  126.                                                 End If
  127.                                         Next
  128.                                 Next
  129.                                 j = j + y
  130.                         Wend
  131.                         i = i + x
  132.                 Wend
  133. End Select
  134. UnlockBuffer()
  135. SetBuffer currbuff
  136. Return destin
  137. End Function
  138.  
  139. ;IMAGE_SCANLINE
  140. ;Adds a scanline effect on alternate lines (intensity and h/v direction of your choice)
  141. ;
  142. ;source = source image handle
  143. ;intensity = 0 to 100% as an integer
  144. ;option = 1: horizontal (default), 2: vertical
  145. Function Image_Scanline(source,intensity#,option)
  146. currbuff = GraphicsBuffer()
  147. If intensity > 100 Then
  148.         intensity = 100
  149. Else If intensity < 0 Then
  150.         intensity = 0
  151. End If
  152. intensity# = 1+(intensity/100)
  153. If option <> 1 And option <> 2 Then
  154.         option = 1
  155. End If
  156. destin = CopyImage (source)
  157. SetBuffer ImageBuffer(destin)
  158. LockBuffer()
  159. Select option
  160.         Case 2  ;vertical
  161.                 For i = 0 To ImageWidth(destin)-1 Step 2
  162.                         For j = 0 To ImageHeight(destin)-1
  163.                                 col = ReadPixelFast(i,j) And $FFFFFF
  164.                                 redlevel = ((col Shr 16) And $FF) / intensity
  165.                                 greenlevel = ((col Shr 8) And $FF) / intensity
  166.                                 bluelevel = (col And $FF) / intensity
  167.                                 argb = (bluelevel Or (greenlevel Shl 8) Or (redlevel Shl 16) Or (255 Shl 24))
  168.                                 WritePixelFast i,j,argb
  169.                         Next
  170.                 Next
  171.         Default ;horizontal
  172.                 For i = 0 To ImageWidth(destin)-1
  173.                         For j = 0 To ImageHeight(destin)-1 Step 2
  174.                                 col = ReadPixelFast(i,j) And $FFFFFF
  175.                                 redlevel = ((col Shr 16) And $FF) / intensity
  176.                                 greenlevel = ((col Shr 8) And $FF) / intensity
  177.                                 bluelevel = (col And $FF) / intensity
  178.                                 argb = (bluelevel Or (greenlevel Shl 8) Or (redlevel Shl 16) Or (255 Shl 24))
  179.                                 WritePixelFast i,j,argb
  180.                         Next
  181.                 Next
  182. End Select
  183. UnlockBuffer()
  184. SetBuffer currbuff
  185. Return destin
  186. End Function
  187.  
  188. ;IMAGE_COLOURISE
  189. ;Turns an image into hues of an RGB colour of your chosing (2 modes)
  190. ;
  191. ;source = source image handle
  192. ;red, green, blue = RGB values to aim toward
  193. ;option = 1: true colourise ala PSP (default), 2: alternate colourise
  194. Function Image_Colourise(source,red#,green#,blue#,option)
  195. currbuff = GraphicsBuffer()
  196. red# = red#/255
  197. green# = green#/255
  198. blue# = blue#/255
  199. If option <> 1 And option <> 2 Then
  200.         option = 1
  201. End If
  202.  
  203. destin = CopyImage (source)
  204. SetBuffer ImageBuffer(destin)
  205. LockBuffer()
  206. For i = 0 To ImageWidth(destin)-1
  207.         For j = 0 To ImageHeight(destin)-1
  208.                 col = ReadPixelFast(i,j) And $FFFFFF
  209.                 redlevel = (col Shr 16) And $FF
  210.                 greenlevel = (col Shr 8) And $FF
  211.                 bluelevel = col And $FF
  212.                 greylevel = Int(0.298039215 * redlevel) + Int(0.588235293 * greenlevel) + Int(0.109803921 * bluelevel)
  213.                 Select option
  214.                         Case 2  ;alternate colourise
  215.                                 redlevel = Int(greylevel*red)
  216.                                 greenlevel = Int(greylevel*green)
  217.                                 bluelevel = Int(bluelevel*blue)
  218.                         Default ;true colorise (PSP emulation)
  219.                                 If greylevel >= 128 Then
  220.                                         redlevel = 255 * red + (1-red)*(greylevel-(255-greylevel))
  221.                                         greenlevel = 255 * green + (1-green)*(greylevel-(255-greylevel))
  222.                                         bluelevel = 255 * blue + (1-blue)*(greylevel-(255-greylevel))
  223.                                 Else
  224.                                         redlevel = Int(greylevel*red)*2
  225.                                         greenlevel = Int(greylevel*green)*2
  226.                                         bluelevel = Int(greylevel*blue)*2
  227.                                 End If
  228.                 End Select
  229.                 argb = (bluelevel Or (greenlevel Shl 8) Or (redlevel Shl 16) Or (255 Shl 24))
  230.                 WritePixelFast i,j,argb
  231.         Next
  232. Next
  233. UnlockBuffer()
  234. SetBuffer currbuff
  235. Return destin
  236. End Function
  237.  
  238. ;IMAGE_BRIGHTNESS
  239. ;Alters an images brightness and contrast
  240. ;
  241. ;NOTES: contrast equation not 100% accurate, but a bloody close approximation! ;)
  242. ;
  243. ;source = source image handle
  244. ;brightness = RGB level offset in the range -255 to 255
  245. ;contrast = contrast in the range -100% to 100% as an integer
  246. Function Image_Brightness(source,brightness,contrast#)
  247. currbuff = GraphicsBuffer()
  248. destin = CopyImage (source)
  249. If contrast# > 100 Then
  250.         contrast# = 100
  251. Else If contrast# < -100 Then
  252.         contrast# = -100
  253. End If
  254. If contrast# >= 0 Then
  255.         contrast# = (contrast#/(101-contrast#))
  256. Else
  257.         contrast# = (0-(contrast#/50))*(contrast#/(101-contrast#))
  258. End If
  259. SetBuffer ImageBuffer(destin)
  260. LockBuffer()
  261. For i = 0 To ImageWidth(destin)-1
  262.         For j = 0 To ImageHeight(destin)-1
  263.                 col = ReadPixelFast(i,j) And $FFFFFF
  264.                 redlevel = (col Shr 16) And $FF
  265.                 greenlevel = (col Shr 8) And $FF
  266.                 bluelevel = col And $FF
  267.                 If contrast <= 0 Then
  268.                         If redlevel < 128 Then
  269.                                 redlevel = Int(redlevel - (127-redlevel)*contrast) + brightness
  270.                         Else
  271.                                 redlevel = Int(redlevel + (redlevel-127)*contrast) + brightness
  272.                         End If
  273.                         If greenlevel < 128 Then
  274.                                 greenlevel = Int(greenlevel - (127-greenlevel)*contrast) + brightness
  275.                         Else
  276.                                 greenlevel = Int(greenlevel + (greenlevel-127)*contrast) + brightness
  277.                         End If
  278.                         If bluelevel < 128 Then
  279.                                 bluelevel = Int(bluelevel - (127-bluelevel)*contrast) + brightness
  280.                         Else
  281.                                 bluelevel = Int(bluelevel + (bluelevel-127)*contrast) + brightness
  282.                         End If
  283.                 Else
  284.                         If redlevel < 128 Then
  285.                                 redlevel = Int(redlevel + brightness)
  286.                                 redlevel = redlevel - (127-redlevel)*contrast
  287.                         Else
  288.                                 redlevel = Int(redlevel + brightness)
  289.                                 redlevel = redlevel + (redlevel-127)*contrast
  290.                         End If
  291.                         If greenlevel < 128 Then
  292.                                 greenlevel = Int(greenlevel + brightness)
  293.                                 greenlevel = greenlevel - (127-greenlevel)*contrast
  294.                         Else
  295.                                 greenlevel = Int(greenlevel + brightness)
  296.                                 greenlevel = greenlevel + (greenlevel-127)*contrast
  297.                         End If
  298.                         If bluelevel < 128 Then
  299.                                 bluelevel = Int(bluelevel + brightness)
  300.                                 bluelevel = bluelevel - (127-bluelevel)*contrast
  301.                         Else
  302.                                 bluelevel = Int(bluelevel + brightness)
  303.                                 bluelevel = bluelevel + (bluelevel-127)*contrast
  304.                         End If
  305.                 End If
  306.                 If redlevel > 255 Then
  307.                         redlevel = 255
  308.                 End If
  309.                 If redlevel < 0 Then
  310.                         redlevel = 0
  311.                 End If
  312.                 If greenlevel > 255 Then
  313.                         greenlevel = 255
  314.                 End If
  315.                 If greenlevel < 0 Then
  316.                         greenlevel = 0
  317.                 End If
  318.                 If bluelevel > 255 Then
  319.                         bluelevel = 255
  320.                 End If
  321.                 If bluelevel < 0 Then
  322.                         bluelevel = 0
  323.                 End If
  324.                
  325.                 argb = (bluelevel Or (greenlevel Shl 8) Or (redlevel Shl 16) Or (255 Shl 24))
  326.                 WritePixelFast i,j,argb
  327.         Next
  328. Next
  329. UnlockBuffer()
  330. SetBuffer currbuff
  331. Return destin
  332. End Function
  333.  
  334. ;IMAGE_NEGATIVE
  335. ;Turns an image into it's negative form.
  336. ;
  337. ;source = source image handle
  338. Function Image_Negative(source)
  339. currbuff = GraphicsBuffer()
  340. destin = CopyImage (source)
  341. SetBuffer ImageBuffer(destin)
  342. LockBuffer()
  343. For i = 0 To ImageWidth(destin)-1
  344.         For j = 0 To ImageHeight(destin)-1
  345.                 col = ReadPixelFast(i,j) And $FFFFFF
  346.                 redlevel = 255-((col Shr 16) And $FF)
  347.                 greenlevel = 255-((col Shr 8) And $FF)
  348.                 bluelevel = 255-(col And $FF)
  349.                 argb = (bluelevel Or (greenlevel Shl 8) Or (redlevel Shl 16) Or (255 Shl 24))
  350.                 WritePixelFast i,j,argb
  351.         Next
  352. Next
  353. UnlockBuffer()
  354. SetBuffer currbuff
  355. Return destin
  356. End Function
  357.  
  358. ;IMAGE_FLOYDDITHER
  359. ;Dithers an image using Floyd-Steinberg approximation into 2 colours
  360. ;
  361. ;source = source image handle
  362. ;optional parameters (defaults given will be used if omitted)
  363. ;erroroffset = multiplier for error#
  364. ;redhigh,greenhigh,bluehigh = RGB values for light pixels
  365. ;redlow,greenlow,bluelow = RGB values for dark pixels
  366. Function Image_FloydDither(source,erroroffset#=1,redhigh=255,greenhigh=255,bluehigh=255,redlow=0,greenlow=0,bluelow=0)
  367. currbuff = GraphicsBuffer()
  368. destin = CopyImage (source)
  369. Dim floydsarray#(ImageWidth(destin),ImageHeight(destin))
  370. SetBuffer ImageBuffer(destin)
  371. LockBuffer()
  372. ;pass one - read greylevels into array
  373. For i = 0 To ImageWidth(destin)-1
  374.         For j = 0 To ImageHeight(destin)-1
  375.                 col = ReadPixelFast(i,j) And $FFFFFF
  376.                 redlevel = (col Shr 16) And $FF
  377.                 greenlevel = (col Shr 8) And $FF
  378.                 bluelevel = col And $FF
  379.                 greylevel# = Int(((222 * redlevel) + (707 * greenlevel) + (71 * bluelevel))/1000)
  380.                 floydsarray(i,j) = greylevel#/255
  381.                 argb = (greylevel Or (greylevel Shl 8) Or (greylevel Shl 16) Or (255 Shl 24))
  382.                 WritePixelFast i,j,argb
  383.         Next
  384. Next
  385. ;pass two - dither based on greylevels
  386. For i = 0 To ImageWidth(destin)-1
  387.         For j = 0 To ImageHeight(destin)-1
  388.                 If floydsarray(i,j) < 0.5 Then
  389.                         bright = 0
  390.                 Else
  391.                         bright = 1
  392.                 End If
  393.                 error# = erroroffset*(floydsarray(i,j) - bright)
  394.                 If (j+1 <= ImageHeight(destin)-1) Then
  395.                         floydsarray(i,j+1) = floydsarray(i,j+1) + error#*7/16
  396.                 End If
  397.                 If j-1 >=0 Then
  398.                         If (i+1 <= ImageWidth(destin)-1) Then
  399.                                 floydsarray(i+1,j-1) = floydsarray(i+1,j-1) + error#*3/16
  400.                         End If
  401.                 End If
  402.                 If (i+1 <= ImageWidth(destin)-1) Then
  403.                         floydsarray(i+1,j) = floydsarray(i+1,j) + error#*5/16
  404.                 End If
  405.                 If (i+1 <= ImageWidth(destin)-1) And (j+1 <= ImageHeight(destin)-1) Then
  406.                         floydsarray(i+1,j+1) = floydsarray(i+1,j+1) + error#*1/16
  407.                 End If
  408.         Next
  409. Next
  410. ;pass three - write white or black pixels from array
  411. For i = 0 To ImageWidth(destin)-1
  412.         For j = 0 To ImageHeight(destin)-1
  413.                 If floydsarray(i,j) > 1 Then
  414.                         floydsarray(i,j) = 1
  415.                 ElseIf floydsarray(i,j) < 0 Then
  416.                         floydsarray(i,j) = 0
  417.                 End If
  418.                 If floydsarray(i,j) < 0.5 Then
  419.                         argb = (bluelow Or (greenlow Shl 8) Or (redlow Shl 16) Or (255 Shl 24))
  420.                 Else
  421.                         argb = (bluehigh Or (greenhigh Shl 8) Or (redhigh Shl 16) Or (255 Shl 24))
  422.                 End If
  423.                 WritePixelFast i,j,argb
  424.         Next
  425. Next
  426. UnlockBuffer()
  427. SetBuffer currbuff
  428. Return destin
  429. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal