Author Topic: Black and White Image Converter  (Read 4172 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Black and White Image Converter
« on: November 28, 2021, 01:30:59 am »
So, as you guys may have noticed in the discussion forum, I'm currently playing around and working with a little Xmas program which should have several little games in it.  The first "game" which I'm working on is a simple coloring book style program which lets you have fun and color, save, or print some Christmas pictures.  One glitch which I was hit with right off the bat is the problem with PAINT failing and coloring the whole dang screen at once.   The reason?? 

The images are grayscale and have multiple shades of black in them, which doesn't form a nice single color for either coloring or a border.   (It's always something to distract a person when trying to program, now ain't it!)

My solution:

Code: QB64: [Select]
  1.  WS = _NewImage(600, 360, 32)
  2.  
  3. ReDim As String D(0), F(0)
  4. GetLists "Coloring Sheets", D(), F()
  5.  
  6. For i = 1 To UBound(f)
  7.     image = _LoadImage("Coloring Sheets/" + F(i), 32)
  8.     _PutImage , image: _FreeImage image
  9.     _Dest CS: _Source WS
  10.     Sleep
  11.     For x = 0 To 599
  12.         For y = 0 To 359
  13.             r = _Red32(Point(x, y))
  14.             g = _Green32(Point(x, y))
  15.             b = _Blue32(Point(x, y))
  16.             If r > 200 Or g > 200 Or b > 200 Then PSet (x, y), &HFFFFFFFF Else PSet (x, y), &HFF000000
  17.         Next
  18.     Next
  19.     Sleep
  20.  
  21.  
  22.  
  23.  
  24. Sub GetLists (SearchDirectory As String, DirList() As String, FileList() As String)
  25.     Declare CustomType Library ".\direntry"
  26.         Function load_dir& (s As String)
  27.         Function has_next_entry& ()
  28.         Sub close_dir ()
  29.         Sub get_next_entry (s As String, flags As Long, file_size As Long)
  30.     End Declare
  31.  
  32.     Dim flags As Long, file_size As Long, DirCount As Long, FileCount As Long, length As Long
  33.     Dim nam$, slash$
  34.     ReDim _Preserve DirList(1000), FileList(1000)
  35.     DirCount = 0: FileCount = 0
  36.     $If WIN Then
  37.         slash$ = "\"
  38.     $Else
  39.         slash$ = "/"
  40.     $End If
  41.     If Right$(SearchDirectory$, 1) <> "/" And Right$(SearchDirectory$, 1) <> "\" Then SearchDirectory$ = SearchDirectory$ + slash$
  42.  
  43.     If load_dir(SearchDirectory + Chr$(0)) Then
  44.         Do
  45.             length = has_next_entry
  46.             If length > -1 Then
  47.                 nam$ = Space$(length)
  48.                 get_next_entry nam$, flags, file_size
  49.                 If _DirExists(SearchDirectory + nam$) Then
  50.                     DirCount = DirCount + 1
  51.                     If DirCount > UBound(DirList) Then ReDim _Preserve DirList(UBound(DirList) + 100)
  52.                     DirList(DirCount) = nam$
  53.                 ElseIf _FileExists(SearchDirectory + nam$) Then
  54.                     FileCount = FileCount + 1
  55.                     If FileCount > UBound(FileList) Then ReDim _Preserve FileList(UBound(FileList) + 100)
  56.                     FileList(FileCount) = nam$
  57.                 Else 'This else should never actually trigger
  58.                     Print: Print: Print "zzz...  Unknown file found: "; SearchDirectory; slash$; nam$, _DirExists(nam$)
  59.                     Beep: Sleep ' alert the user to
  60.                 End If
  61.             End If
  62.         Loop Until length = -1
  63.     End If
  64.     close_dir
  65.  
  66.     ReDim _Preserve DirList(DirCount)
  67.     ReDim _Preserve FileList(FileCount)
  68.  

Now, I can either SaveImage these into the world's smallest JPG/PNG (I can't imagine they'd be very large at all once compression hits with only 2 colors involved in each image), or I can just use the converter as is in my main program and transform those into two color images on the fly for my coloring app. 

With the two SLEEP statements in there, you can see the subtle difference as our almost-whites and almost-blacks end up turning into solid-whites and solid-blacks. 

I don't imagine there'll be any issues now with PAINT being able to find the proper borders for the images fill areas.  ;)
* Coloring Sheets.7z (Filesize: 2.89 MB, Downloads: 157)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Black and White Image Converter
« Reply #1 on: November 28, 2021, 10:39:00 am »
@SMcNeill
Hi. The reason you have gray pixels in your images is that JPG compression is used, because you know that JPG adds up adjacent pixels during compression. Black + white = gray. The only format that won't do this to you is either PNG or BMP. With that BMP, you would even reach half the file size (height x width / 8) + 62 bytes (compared to the current JPG file size), but it would probably be easiest to convert to PNG using your library, it is a lossless format and so it should not do artifacts after you run your program to get a black and white image from thij JPGs. I appreciate your idea, the coloring books are perfect.

After all - I don't believe my eyes. Do you use POINT and PSET? You, our teacher with MEM?    :) 


Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Black and White Image Converter
« Reply #2 on: November 28, 2021, 01:53:34 pm »
Hmm... I get an error: LIBRARY not found on current line. Caused by (or after): "DECLARE CUSTOMTYPE LIBRARY ".\\direntry",10
Logic is the beginning of wisdom.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Black and White Image Converter
« Reply #3 on: November 28, 2021, 02:19:58 pm »
Hmm... I get an error: LIBRARY not found on current line. Caused by (or after): "DECLARE CUSTOMTYPE LIBRARY ".\\direntry",10

Aye.  You'll need the direntry.h library for it to work with the GetDir sub.  Just do a quick search of the forums; there's a thousand copies of it on here already.  It's just like falcon.h -- a header file which everyone should have and keep in their QB64 folder, in my opinion.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Black and White Image Converter
« Reply #4 on: November 28, 2021, 02:32:51 pm »
Thanks Steve.

direntry.h and falcon.h ... will do...

I should have remembered that... but, for a newbie, a list dependencies might be helpful... or a link to them... ;)
Logic is the beginning of wisdom.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Black and White Image Converter
« Reply #5 on: November 28, 2021, 02:50:53 pm »
Steve,

'falcon' was already there... But, with 'direntry', the program ran without error.

Thank you for the assist. Much appreciated.

J
Logic is the beginning of wisdom.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Black and White Image Converter
« Reply #6 on: November 28, 2021, 05:28:19 pm »
@SMcNeill
Hi. The reason you have gray pixels in your images is that JPG compression is used, because you know that JPG adds up adjacent pixels during compression. Black + white = gray. The only format that won't do this to you is either PNG or BMP. With that BMP, you would even reach half the file size (height x width / 8) + 62 bytes (compared to the current JPG file size), but it would probably be easiest to convert to PNG using your library, it is a lossless format and so it should not do artifacts after you run your program to get a black and white image from thij JPGs. I appreciate your idea, the coloring books are perfect.

After all - I don't believe my eyes. Do you use POINT and PSET? You, our teacher with MEM?    :)

I almost always start out with POINT and PSET to get things working, and then swap over to MEM when speed is the concern.

Many thanks in reminding me about JPG and how it works.  I *knew* it, but never thought about it.  You should've seen me last night scratching my head as paint constantly bled through my images...  I was opening FILE$, blacking out the grays, and then overwtiting FILE$ with the new image...

So basically I was making my JPG into another JPG, and, as you can guess, that didn't work well!   Removing the extension (LEFT$(LEN(FILE$) - 3) and adding "PNG" to convert to lossless graphics made all my troubles go away!

/SIGH...

The obvious things we don't pay attention to, until it's pointed out to us.  ;D

Anywho...  V0.3 is up now, and the coloring should be complete.  (Though I don't have a working printer to test the PRINT option at the moment, and the Save screen needs a prettier makeover.  At least it all appears to be working as intended.)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!