PureBasic Forum
http://forums.purebasic.com/english/

Saving .PNG images in Linux
http://forums.purebasic.com/english/viewtopic.php?f=15&t=70810
Page 1 of 1

Author:  HarrysLad [ Sun Jun 03, 2018 1:35 pm ]
Post subject:  Saving .PNG images in Linux

I've written a few simple apps that compile and run as expected on macOS and Windows but now I'm attempting to offer Linux versions as well.
There're a few things to sort out but a major problem at the moment centres around saving an image in .PNG format.

Code:
Procedure imageSave(Image.l)

  Define file$, PathPart$, FilePart$, buffer.l, w.i, h.i
 
  file$ = SaveFileRequester("Save Image as PNG", "Image.png", "Images (.png)|*.png", 0)
  If file$ > ""
    w = GadgetWidth(Image)
    h = GadgetHeight(Image)
    PathPart$ = GetPathPart(file$)
    FilePart$ = GetFilePart(file$, #PB_FileSystem_NoExtension)
    file$ = PathPart$ + FilePart$ + ".png"
    CreateImage(buffer, w, h)
    StartDrawing(ImageOutput(buffer))
    DrawImage(GetGadgetAttribute(Image, #PB_Canvas_Image), 0, 0)
    FrontColor($0)
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(0, 0, w, h)
    StopDrawing()
    SaveImage(buffer, file$)         
    FreeImage(buffer)
    MessageRequester("Image:", "Saved as:" + #CR$ + file$)
  EndIf
   
EndProcedure


This same code works perfectly in macOS and Windows but, while it writes a .png file at the requested destination, Linux reckons "Fatal error reading PNG image file: Not a PNG file" when I try to view it.

Tested on Windows 7, 10, macOS High Sierra ... OK
Ubuntu 16.04 LTS, Mint 18 ... not so good.

Any ideas what I'm doing wrong?

TIA
Dave

Author:  StarBootics [ Sun Jun 03, 2018 2:11 pm ]
Post subject:  Re: Saving .PNG images in Linux

Did you use the UsePNGImageEncoder() somewhere in your program ?
Code:
Procedure imageSave(Image.l)
 
  Define file$, PathPart$, FilePart$, buffer.l, w.i, h.i
 
  file$ = SaveFileRequester("Save Image as PNG", "Image.png", "Images (.png)|*.png", 0)
  If file$ > ""
    w = GadgetWidth(Image)
    h = GadgetHeight(Image)
    PathPart$ = GetPathPart(file$)
    FilePart$ = GetFilePart(file$, #PB_FileSystem_NoExtension)
    file$ = PathPart$ + FilePart$ + ".png"
    CreateImage(buffer, w, h)
    StartDrawing(ImageOutput(buffer))
    DrawImage(GetGadgetAttribute(Image, #PB_Canvas_Image), 0, 0)
    FrontColor($0)
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(0, 0, w, h)
    StopDrawing()
    SaveImage(buffer, file$, #PB_ImagePlugin_PNG)         
    FreeImage(buffer)
    MessageRequester("Image:", "Saved as:" + #CR$ + file$)
  EndIf
 
EndProcedure

UsePNGImageEncoder()

If OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 10, 10, 200, 200)
  imageSave(0)
  Repeat
    Event = WaitWindowEvent()
   
    If Event = #PB_Event_Gadget And EventGadget() = 0
      If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
        If StartDrawing(CanvasOutput(0))
          x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
          y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
          Circle(X, Y, 10, RGB(Random(255), Random(255), Random(255)))
          StopDrawing()
        EndIf
      EndIf
    EndIf   
   
  Until Event = #PB_Event_CloseWindow
EndIf


The code above work on linux Ubuntu 18.04.

Best regards
StarBootics

Author:  HarrysLad [ Sun Jun 03, 2018 2:28 pm ]
Post subject:  Re: Saving .PNG images in Linux

StarBootics wrote:
Did you use the UsePNGImageEncoder() somewhere in your program ?

Yes but - clutching at straws - I have compiled versions without. Same result as before ... works on Win & macOS, doesn't on Linux.

StarBootics wrote:
By the way without a working example it's very hard to tell.

You're right. I just thought (hoped) I was making a silly/obvious error somewhere.
I'll write a little app to demonstrate.

ATB
Dave

Author:  Marc56us [ Sun Jun 03, 2018 3:03 pm ]
Post subject:  Re: Saving .PNG images in Linux

Always check after create

Not only:
Code:
SaveImage(buffer, file$)

But:
Code:
If Not SaveImage(buffer, file$)
  Debug "SaveImage failed :-("
  ProcedureReturn
EndIf
  Debug "Size of file saved: " + FileSize(file$)

FileSize must be > 0
if FileSize = 0 something is wrong (files rights ? directory rights ? user rights ? file exist ? file is directory ?)

Check on shell
$ file <your file>
must be binary file

:wink:

Author:  Trond [ Sun Jun 03, 2018 3:34 pm ]
Post subject:  Re: Saving .PNG images in Linux

Quote:
I've written a few simple apps that compile and run as expected on macOS and Windows
...
This same code works perfectly in macOS and Windows
No, it doesn't, it actually works the same under all OSes. The difference lies in how the OSes handle opening a bmp file with a png extension. Because your code saves a bmp file, not a png file. That's why you get the error message "not a png file". :)

New code:
Code:
SaveImage(buffer, file$,  #PB_ImagePlugin_PNG)

Author:  Marc56us [ Sun Jun 03, 2018 3:52 pm ]
Post subject:  Re: Saving .PNG images in Linux

HarrysLad, Trond and StarBootics are right

Your sample : Image1.png
StarBootics sample: Image2.png
Code:
$ file Image*
Image1.png: PC bitmap, Windows 3.x format, 200 x 200 x 24
Image2.png: PNG image data, 200 x 200, 8-bit/color RGB, non-interlaced

:wink:

https://www.purebasic.com/documentation/image/saveimage.html
Without specify plugin, Save the image in BMP (default)

Author:  HarrysLad [ Sun Jun 03, 2018 4:00 pm ]
Post subject:  Re: Saving .PNG images in Linux

Curiouser and curiouser ...
You might have guessed but I'm new to Linux. :D
I've incorporated all of your suggestions and it works in Win/OSX but not Linux.
However ...
The image opens OK using Gimp and FireFox and ImageMajick (whatever that is) but the Image Viewer stops with the error.
This is with both Umbuntu and Mint.

Trond wrote:
Quote:
I've written a few simple apps that compile and run as expected on macOS and Windows
...
This same code works perfectly in macOS and Windows
No, it doesn't, it actually works the same under all OSes. The difference lies in how the OSes handle opening a bmp file with a png extension. Because your code saves a bmp file, not a png file. That's why you get the error message "not a png file". :)

New code:
Code:
SaveImage(buffer, file$,  #PB_ImagePlugin_PNG)



Trouble is if I add the '#PB_ImagePlugin_PNG' it doesn't work in Windows, OSX or Linux ..

Code:
; PNGTesting.pb

Enumeration
 
  ; main window
  #WINDOW_MAIN
  ; image buffer
  #IMAGE_BUFFER
  ; image view
  #IMAGE_VIEW
 
EndEnumeration

Procedure ImageSave(Image.l)

  Define file$, PathPart$, FilePart$, buffer.l, w.i, h.i
 
  file$ = SaveFileRequester("Save Reticle as PNG", "Image.png", "Images (.png)|*.png", 0)
  If file$ > ""
    w = GadgetWidth(Image)
    h = GadgetHeight(Image)
    PathPart$ = GetPathPart(file$)
    FilePart$ = GetFilePart(file$, #PB_FileSystem_NoExtension)
    file$ = PathPart$ + FilePart$ + ".png"
    CreateImage(buffer, w, h)
    StartDrawing(ImageOutput(buffer))
      DrawImage(GetGadgetAttribute(Image, #PB_Canvas_Image), 0, 0)
      FrontColor($0)
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(0, 0, w, h)
      StopDrawing()
      If SaveImage(buffer, file$,  #PB_ImagePlugin_PNG)   
        Debug "imageSave OK ("+ FileSize(file$)+" bytes)"
      Else
        Debug "imageSave failed ... "
      EndIf
      FreeImage(buffer)
    MessageRequester("Image:", "Saved as:" + #CR$ + file$)
  EndIf
   
EndProcedure

;
; main bit
;

UsePNGImageDecoder()

OpenWindow(#WINDOW_MAIN, 0, 0, 410, 410, "PNGTesting",#PB_Window_ScreenCentered)
CanvasGadget(#IMAGE_VIEW, 5, 5, 400, 400) 
CatchImage(#IMAGE_BUFFER, ?PNGImage)
If StartDrawing(CanvasOutput(#IMAGE_VIEW))
  Box(0, 0, 500, 500, #White)
  DrawAlphaImage(ImageID(#IMAGE_BUFFER), 0, 0)
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(0, 0, 400, 400, #Black)   
  StopDrawing()
EndIf
GadgetToolTip(#IMAGE_VIEW, "Right click to save, Escape to Quit")

AddKeyboardShortcut(#WINDOW_MAIN, #PB_Shortcut_Escape,2)

Repeat
 
  Event = WaitWindowEvent(1)
  If Event = #PB_Event_CloseWindow Or (Event = #PB_Event_Menu And EventMenu() = 2)
    Quit = #True                   
  EndIf
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #IMAGE_VIEW
          Select EventType()
            Case #PB_EventType_RightClick
              ImageSave(#IMAGE_VIEW)
          EndSelect
      EndSelect
  EndSelect

Until Quit = #True   
End

DataSection

  PNGImage:
  IncludeBinary "HALFMD.png"
 
EndDataSection


Dave

Author:  Marc56us [ Sun Jun 03, 2018 4:13 pm ]
Post subject:  Re: Saving .PNG images in Linux

UsePNGImageEncoder()
Not
UsePNGImageDecoder()

(and put it at top of code)

And before modify your code, test StarBootics code, it's a standalone sample.

:wink:

Author:  HarrysLad [ Sun Jun 03, 2018 4:27 pm ]
Post subject:  Re: Saving .PNG images in Linux

Marc56us wrote:
UsePNGImageEncoder()
Not
UsePNGImageDecoder()

(and put it at top of code)

And before modify your code, test StarBootics code, it's a standalone sample.

:wink:

Yup, I thought it must be something simple/stupid - although I actually need both UsePNGImageEncoder() and UsePNGImageDecoder() presumably because I'm reading in and writing out .PNG files.

I'm sure another problem'll be along shortly but for now, thanks for your help.
Dave

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/