Author Topic: SaveImage v2.1  (Read 618 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3679
    • Steve’s QB64 Archive Forum
SaveImage v2.1
« on: August 12, 2019, 03:14:44 AM »
Unless somebody reports issues with anything, SaveImage v2.0 is now here.



Inside the archive below is a couple of quick demos which illustrate how to save a QB64 screen image in either BMP or PNG format; how one can easily turn a text screen into a 256 color graphic screen with one simple command; and how to compress and inflate strings or programs quickly and easily. 

Commands should be simple enough that everyone can figure them out without any real effort involved.

To Deflate/Inflate a string/file:
Code: QB64: [Select]
  1. '$include:'saveimage.bi'
  2. text$ = "Whatever the heck it is that we might want to compress, be that a long string of input, a binary file (just load the whole file into a single string and then deflate it), or whatever else is wanted)."
  3. de$ = Deflate(text$) ' <-- This is how simple it is to deflate the string
  4. t$ = Inflate(de$) '  <-- This is how simple it is to inflate that deflated string
  5. '$include:'saveimage.bm'

To turn a text screen into a graphic screen:
Code: QB64: [Select]
  1. '$include:'saveimage.bi'
  2. PRINT "Hello World.  This is a SCREEN 0 screen which I'm printing on."
  3. x = TextScreenToImage256(0) 'And a quick example of how to turn a text screen into a 256 color image screen
  4. SCREEN x 'swap screens
  5. CIRCLE (320, 240), 100, 40 'And draw a circle on it
  6. LOCATE 2,1: PRINT "And now it's been converted to a 256 color graphical screen.  See the circle on it??"
  7. '$include:'saveimage.bm'
  8.  

To save an image (from any QB64 screen mode -- even SCREEN 0 text screens work!):
Code: QB64: [Select]
  1. '$Include:'SaveImage.BI'
  2. SCREEN _NEWIMAGE(1280, 720, 32)
  3. InitialImage$ = "Volcano Logo.jpg"
  4. exportimage1$ = "testimage.png"
  5. exportimage2$ = "testimage.bmp"
  6.  
  7.  
  8. l& = _LOADIMAGE(InitialImage$)
  9. _PUTIMAGE , l& 'And this line
  10.  
  11. Result = SaveImage(exportimage1$, 0, 0, 0, _WIDTH, _HEIGHT)
  12. IF Result = 1 THEN 'file already found on drive
  13.     KILL exportimage1$ 'delete the old file
  14.     Result = SaveImage(exportimage1$, 0, 0, 0, _WIDTH, _HEIGHT) 'save the new one again
  15. PRINT Result
  16. PRINT "Our initial Image"
  17. IF Result < 0 THEN PRINT "Successful PNG export" ELSE PRINT "PNG Export failed.": ' END
  18.  
  19.  
  20.  
  21. Result = SaveImage(exportimage2$, 0, 0, 0, _WIDTH, _HEIGHT)
  22. IF Result = 1 THEN 'file already found on drive
  23.     KILL exportimage2$ 'delete the old file
  24.     Result = SaveImage(exportimage2$, 0, 0, 0, _WIDTH, _HEIGHT) 'save the new one again
  25. PRINT Result
  26. PRINT "Our initial Image"
  27. IF Result < 0 THEN PRINT "Successful BMP export" ELSE PRINT "BMP Export failed.": END
  28.  
  29.  
  30.  
  31.  
  32.  
  33. zz& = _LOADIMAGE(exportimage1$, 32) 'Even though we saved them in 256 color mode, we currently have to force load them as 32 bit images as _LOADIMAGE doesn't support 256 color pictures yet
  34. IF zz& <> -1 THEN
  35.     SCREEN zz&
  36.     PRINT "Image Handle: "; zz&, exportimage1$
  37.     PRINT "Successful Import using _LOADIMAGE"
  38.     PRINT "ERROR - Not Loading the new image with _LOADIMAGE."
  39.  
  40.  
  41.  
  42. zz& = _LOADIMAGE(exportimage1$, 32) 'Even though we saved them in 256 color mode, we currently have to force load them as 32 bit images as _LOADIMAGE doesn't support 256 color pictures yet
  43. IF zz& <> -1 THEN
  44.     SCREEN zz&
  45.     PRINT "Image Handle: "; zz&, exportimage2$
  46.     PRINT "Successful Import using _LOADIMAGE"
  47.     PRINT "ERROR - Not Loading the new image with _LOADIMAGE."
  48.  
  49.  
  50.  
  51.  
  52. '$INCLUDE:'SaveImage.BM'



So what does v2.0 bring us that the last v1.7 didn't do?

* Minor bug fix when trying to save 32-bit PNG images of a SCREEN 0 text screen.
* Some additional error checking for... everything really.
* The new ability to save images in *.JPG format.

There's a lot of stuff packaged inside the library here, but the main ones which a user might decide to call is the following:
FUNCTION SaveImage (file$, image&, x1%, y1%, x2%, y2%) 
SUB SaveFullImage (filename$)
SUB SaveFullBMP (filename$)
SUB SaveFullJPG (filename$)
SUB SaveBMP (filename$, image&, x1%, y1%, x2%, y2%)
FUNCTION TextScreenToImage256& (image&)
FUNCTION TextScreenToImage32& (image&)
FUNCTION Deflate$ (text$) 
FUNCTION Inflate$ (text$)
FUNCTION PNGExport (file$, imagehandle%, x1%, y1%, x2%, y2%) 
SUB SaveJPG (file$, image&, startx, starty, finishx, finishy)

As you can see, most of these routines can easily be handled by simply using FUNCTION SaveImage, which then decides if it needs to convert from a text screen to a graphic screen, and which save routine to make use of.  I mainly list them separately, in case  anybody may need to call upon the main save routines directly to save a wee bit of processing time.  (Why call a routine to check graphic mode and do a lot of error checking, which then simply hands off the process to another routine, when you can call the end routine correctly and save a few steps each cycle?)

FUNCTION Deflate$ compresses a string which we send it.  Inflate turns that compressed string back into its original state for us.

FUNCTION SaveImage (file$, image&, x1%, y1%, x2%, y2%)  is the main wrapper which handles our image processing. 
file$ is the name of the file you want to save to on the disk.  The filename needs to end with with ".jpg", ".bmp", "png" (capitalized, or not, it doesn't matter generally), so the routine knows what format you're wanting to save to on the disk.
image& is the handle of the image you want to save.
The other 4 values are the X/Y region you want to save to the disk.

FUNCTION TextScreenToImage256& converts a SCREEN 0 style text screen into a 256 color image for us.

FUNCTION TextScreenToImage32& works about the same as the above, except it converts that text screen to a 32-bit color image for us.


Error codes which the program might generate for you are listed below:
Quote
    '-1   All is good.  We think we exported a proper PNG file.
    ' 0   Compression failed.  File is probably corrupt.
    ' 1   File Already Exists.  As these are Binary files, we probably don't want to just overwrite the same file.
    ' 2   Incorrect Alpha settings.  Check for Alpha mode, and Color mode, and look for conflicts.
    ' 3   Bad GrabMode
    ' 4   Bad x1 coordinate
    ' 5   Bad y1 coordinate
    ' 6   Bad x2 coordinate
    ' 7   Bad y2 coordinate
    ' 8   x2 < x1 -- correct this to proceed
    ' 9   y2 < y1 -- correct this to proceed
    '10   Bad color mode.  Either use 256 or 32 color mode.
    '11   Attempted to export a text screen which will not work.
    '12   PNG save is impossible on non-Windows systems.  Can only use BMP or JPG
    '13   Invalid extension, or lack of extension

Note that not all methods are going to report all the error codes.  For example, it's impossible to get error 12 when saving a BMP or JPG file.  If you do get an error message, take a look at the above and see if it helps you sort out what's wrong.  If the error code doesn't help, kindly post the issue for me, and I'll take a look into the situation and see if I can help diagnose the problem and add a better message to the library for future releases.



If the included demo seems complicated, it's really not.  For most people, the usage would be as simple as:

Code: QB64: [Select]
  1. [code=qb64]
  2. '$INCLUDE:'SaveImage.BI'
  3.  
  4. 'Your stuff here
  5. result = SaveImage("filename.BMP",0, 0, 0, _WIDTH, _HEIGHT)
  6. IF result = 1 THEN 'file already exists on the drive
  7.    KILL "filename.BMP" 'if this is what you want to do with it, to get rid of it.  Else handle the problem differently
  8.    result = SaveImage("filename.BMP, 0, 0, 0, _WIDTH, _HEIGHT) 'now try and resave the file, since we got rid of the previous version
  9. END IF
  10.  
  11. '$INCLUDE:'SaveImage.BM'
[/code]



And I believe that's about it.  If there's any questions, glitches, comments, or feedback, leave your concerns below and I'd address them ASAP for you.  ;D
« Last Edit: August 13, 2019, 10:33:06 AM by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3679
    • Steve’s QB64 Archive Forum
Re: SaveImage v2.0
« Reply #1 on: August 12, 2019, 03:27:27 AM »
One thing to add, which folks might want to take into consideration:  The JPG routine is based off old QB45 code converted to fit inside the library, so it takes quite a bit longer to process (about half a second or so on my PC), than the much quicker PNG routine, or the superquick BMP routine (which does no compression for us; just a fast dump of an image file).

If speed is your primary concern, you may want to save as a BMP file.  If lossless file size is your concern, you'd probably want to use the PNG export (if you're a Windows user). 

Just choose what is appropriate for your needs, but be aware that some formats perform better at various tasks than others.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3679
    • Steve’s QB64 Archive Forum
Re: SaveImage v2.1
« Reply #2 on: August 13, 2019, 10:41:46 AM »
File has been updated to version 2.1 which features:

* Image32To256 -- function to convert 32-bit images to 256 color images
* GIF images are now available for export.
* A new, simplified demo for saving in all 4 of the export formats now.

We now support exporting files in *.JPG, *.PNG, *.BMP, and *.GIF formats, and I think that covers the bases for most formats which an user might ever need/want to use.  I honestly doubt I'll look to add any other export formats anytime soon.  (It was several years from when I started with BMP and then added PNG support, and it's been several years since then, and I'm just now adding JPG and GIF support.  Expect years -- if ever -- before you see me add another format for us.)

I was thinking of adding a Convert256To32 routine, but that hardly seems necessary.  _LOADIMAGE loads all 256 color images as 32-bits automatically.  I really don't think there's much need for me to add such a routine, but if someone truly wants it, speak up and I can insert it into the library.  Going from 256 colors to 32-bit certainly is a lot easier than going from 32-bit to 256.  Adding it wouldn't be much work, if it was desired/needed by someone.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!