|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
johannes
Joined: 21 Jan 2011 Posts: 65 Location: Leimen, Germany
|
Posted: Mon Aug 25, 2014 5:19 pm Post subject: How to create a png file from array data? |
|
|
Hello all,
for long time I'm creating fine jpg files from computed pixel arrays using
CALL put_dib_block@(dibfile,a2,a2hres,a2vres,0,0,iCxdim,jCydim,24,ier)
(dibfile has extension .jpg).
Now I want to create an additional png file based on same array a2, but don't know how to create them. I did this experiment.
Code: | i= IMPORT_IMAGE@('{'//dibfile//'}',0,0) ! import jpg in curly brackets
print *,'IMPORT return flag=',i
i= EXPORT_IMAGE@( TRIM(pathmod)//'test.png') !export png
print *,'EXPORT', TRIM(pathmod)//'test.png return flag=',i |
The result is
IMPORT returns i=1 (good)
EXPORT returns i=0 (bad). the file has 0 bytes.
I am sure there is a better way of doing. Should work without any user interaction, either directly from array a2 or using the intermediate jpg.
best regards,
johannes |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Tue Aug 26, 2014 6:54 am Post subject: |
|
|
I don't think there is a direct way to export to a png file from the array.
Your method should work. Are you using a recent salflibc.dll? |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Tue Aug 26, 2014 1:48 pm Post subject: |
|
|
I find that EXPORT_IMAGE@ works successfully for .png format files.
This exports the currently selected drawing surface, which can be either:
the %gr window or
a virtual window created by the calls:
i = create_graphics_region@ (hd_handle, w_width, w_depth)
i = select_graphics_object@ (hd_handle)
If you want to export a DIB array, you may need to copy it to an appropriate graphics region (drawing surface).
DIB arrays appear to be different from the drawing surface or direct addressing of the %gr graphics region. The restrictions on moving between the different types of surfaces can be difficult.
If I recall correctly, my experimenting with direct addressing of the graphics region shows it only worked with the %gr surface and not selected graphics regions. You have to work with what is available.
Over the years I have moved from .pcx to .gif and now .png.
I tried .jpg, but found it to be unsuitable for the colour shaded surfaces I am using.
.pcx was dropped by MS Word (2003?) so became unuseable.
.gif is by far the most compact, but I had problems with the limited colour palette, which was solved by using .png
John |
|
Back to top |
|
|
johannes
Joined: 21 Jan 2011 Posts: 65 Location: Leimen, Germany
|
Posted: Tue Aug 26, 2014 2:26 pm Post subject: |
|
|
Hello Paul,
I tried with 7.10 but same response as 7.00. *.png is not created.
Hello John,
could you please write down the complete set of calls?
Given I have an array a2, which I store into a jpg by now using
CALL put_dib_block@(dibfile,a2,a2hres,a2vres,0,0,iCxdim,jCydim,24,ier)
What to do with a2 until EXPORT_IMAGE@?
Thanks,
johannes |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Aug 27, 2014 2:13 am Post subject: |
|
|
Johannes,
The process I would go through is:
1) determine the size of the DIB graphics area
2) create a graphics area of the appropriate size
i = create_graphics_region@ (hd_handle, w_width, w_depth)
i = select_graphics_object@ (hd_handle)
3) copy the DIB array using DISPLAY_DIB_BLOCK@
4) export the graphics object using EXPORT_IMAGE@ and the appropriate file name extension .png
I am not sure of the history of DIB, but one of the problems with this array is that it is stored as BGR, while %gr graphics region direct addressing is RGB (or the other way round).
There are 3 ways of manipulating graphics that I looked at:
DIB - drawing device independent bitmaps
%gr - direct manipulation of the graphics surface
Off-screen graphics
I use Off-screen graphics as I want to have a graphics image that is not limited by the %gr size. Both DIB or Create_graphics_region@ provide this.
I was looking for direct addressing of the graphics region to improve paint times. I found that "Direct manipulation of the graphics surface" only worked on the %gr region. I considered DIB but unfortunately there are only a few routines to address a DIB array.
I found it easier to work between the %gr, clearwin+ off-screen graphics and my own virtual screen definition. Export_Image@ works with both clearwin surfaces. To improve the speed of setting pixels, rather than use draw_point@, I scanned lines of my own virtual screen definition and draw_line_between@ as typically I have areas of similar colour.
My own drawing surface is a 3D surface to do simple hidden line removal on a larger window and the performance is acceptable.
DIB did not show much performance improvement and a few show stoppers, so I did not persist. Others may be more proficient with DIB but I'd recommend the alternative.
There are lots of ways to do this and the above is what I know that works best.
John |
|
Back to top |
|
|
johannes
Joined: 21 Jan 2011 Posts: 65 Location: Leimen, Germany
|
Posted: Thu Aug 28, 2014 10:34 am Post subject: |
|
|
Hello John,
I have to admit that I have little experience with %gr and DIB.
Meanwhile I tried:
i=create_graphics_region@(ihandle,a2hres,a2vres)
-> i=1
i=select_graphics_object@(ihandle)
-> i=1
call DISPLAY_DIB_BLOCK@( 0,0 ,a2,a2hres,a2vres,0,0,a2hres,a2vres,0,0,ier )
-> ier=0
i= EXPORT_IMAGE@( TRIM(pathmod)//'test.png') !export png
-> i=0
File test.png is not created at all. I would have been lucky if it were empty. What's wrong?
BR, johannes |
|
Back to top |
|
|
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Thu Aug 28, 2014 1:14 pm Post subject: |
|
|
Johannes, I made a few tests and it seems that the png export doesn't work but all others do (???). Here is my code:
Code: | winapp
program test
implicit none
include <windows.ins>
integer*4 i,j,A,lins,cols
real*8 r
character*1 image(120000)
c create 24-bit test image (replace by your own)
lins = 200
cols = 200
image = char(255)
do i = 1,lins
A = 3*(i-1)*cols
do j = 1,3*cols,3
if (mod(i,50) .eq. 0 .or. mod(j,50) .eq. 0) then
image(A+j ) = char(1)
image(A+j+1) = char(1)
image(A+j+2) = char(1)
end if
end do
end do
c off-screen graphics & export
j = create_graphics_region@(4L,cols,lins)
j = select_graphics_object@(4L)
call display_dib_block@(1,1,image,cols,lins,1,1,cols,lins,0,0,i)
r = set_jpeg_quality@(1.D0)
j = export_image@('c:\temp\test.jpg') ! works
j = export_image@('c:\temp\test.bmp') ! works
j = export_image@('c:\temp\test.gif') ! works
j = export_image@('c:\temp\test.png') ! does not work !!
j = delete_graphics_region@(4L)
end |
Funny...
Wilfried |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Aug 28, 2014 1:20 pm Post subject: |
|
|
Johannes,
.png wasn't supported until FTN95 6.35
The documentation for DISPLAY_DIB_BLOCK@ indicates it transfers to the current graphics device (e.g. a %gr window or a printer). I never know if this includes the selected drawing surface, which makes it all a bit more difficult. It has been a few years since I tried DIB and went back to the old ways.
I don't have a DIB array handy, but you could try the following adaptations to your code; Code: | !
! all arguments are I*4 and must be supplied
ihandle = 11
write (*,*) 'create_graphics_region@ inputs :',ihandle,a2hres,a2vres
i = create_graphics_region@ (ihandle,a2hres,a2vres)
write (*,*) 'create_graphics_region@ >',i,' (=1)'
!
i = select_graphics_object@ (ihandle)
write (*,*) 'select_graphics_object@ >',i,' (=1)'
!
call DISPLAY_DIB_BLOCK@( 0,0, a2,a2hres,a2vres, 0,0,a2hres,a2vres,0,0,ier )
write (*,*) 'DISPLAY_DIB_BLOCK@ >',ier,' (=0)'
!
! You could try this but I don't think it is necessary
i = select_graphics_object@ (ihandle)
write (*,*) 'select_graphics_object@ >',i,' (=1)'
!
! .png requires FTN95 version 6.35.
i = EXPORT_IMAGE@ ( 'test.png' ) !export png
write (*,*) 'EXPORT_IMAGE@ .png >',i,' (/=0)'
!
! export .jpg to confirm image is ok
i = EXPORT_IMAGE@ ( 'test.jpg' ) !export jpg to check
write (*,*) 'EXPORT_IMAGE@ .jpg >',i,' (/=0)'
|
Wilfred,
Hopefully you are using FTN95 prior to Ver 6.35. I am still creating .png files with Ver 7.0.
Why didn't you use rank 3 character or integer*1 array ?
integer*4, parameter :: horz = 1900
integer*4, parameter :: vert = 1100
character image(3,horz,vert)*1 ! I think that is the order
My earlier comment about direct manipulation of drawing surface should have said that the colour order is BGR, while the DIB array is RGB. Just something more to create some doubt.
John |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Aug 28, 2014 2:06 pm Post subject: |
|
|
Wilfred,
You have provided a very useful example, which I have expanded to show a few more features that can be confusing.
Moving to a rank 3 allocatable array makes it easier to import a graphics file of general size, using GET_DIB_BLOCK@. Again I don't know what graphics formats are now supported, but if others aren't then we need to transfer via a graphics region.
You need to be careful with the start coordinates. I think they should be 0,0. You can blame a C programmer for this. The following will work, but if you use 1,1 it will not.
It is also useful to compare the different sizes of the resulting graphics files. In this case .png has the best compression.
Code: | winapp
program test3
implicit none
include <windows.ins>
integer*4 i,j,A,lins,cols
integer*4 x,y, HANDLE
real*8 r
character*1, dimension(:,:,:), allocatable :: image
character*1 :: red(3), blue(3), black(3)
! create 24-bit test image (replace by your own)
handle = 4
lins = 250
cols = 550
allocate ( image(3,cols,lins) )
!
red = char(1) ; red(1) = char(255)
blue = char(1) ; blue(3) = char(255)
black = char(1)
!
image = char(255) ! white
do y = 1,lins
image(:,1,y) = red
image(:,cols,y) = red
end do
do x = 1,cols
image(:,x,1) = blue
image(:,x,lins) = blue
end do
!
do y = 2,lins-1
do x = 2,cols-1
if (mod(y,50) .eq. 0 .or. mod(x,50) .eq. 0) image(:,x,y) = black
end do
end do
! off-screen graphics & export
j = create_graphics_region@ (handle,cols,lins)
j = select_graphics_object@ (handle)
!
call display_dib_block@ (0,0,image,cols,lins,0,0,cols,lins,0,0,i)
!
r = set_jpeg_quality@ (1.D0)
j = export_image@ ('c:\temp\test3.jpg') ! works
j = export_image@ ('c:\temp\test3.bmp') ! works
j = export_image@ ('c:\temp\test3.gif') ! works
j = export_image@ ('c:\temp\test3.png') ! does not work !!
j = delete_graphics_region@ (handle)
!
end |
|
|
Back to top |
|
|
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Thu Aug 28, 2014 2:37 pm Post subject: |
|
|
John, I just saw that I use FTN95 version 5.50 on my laptop. I hope that png export works on newer versions. Sorry for the confusion. I have to update my compiler
I always use character*1 for 8- or 24-bits images and integer*2 for 16-bits surface models. What do you think are the advantages using 3D character*1 values?
Wilfried |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Aug 28, 2014 3:35 pm Post subject: |
|
|
Wilfred,
It is a couple of years since I tried to look at DIB, but I was trying to use TYPE structures to make the addressing of the graphics images, especially when trying to manipulate 3-byte RGB or BGR colours.
The Rank 3 array does simplify the 3byte|X|Y addressing.
I also found the use of allocatable arrays helpful when using DIB.
I also tried it with direct addressing, but I recall this only worked with the %gr drawing surface and was no good for create_graphics_region@ images. It might be good to have direct addressing for create_graphics_region@ images, by obtaining the memory address, but the use of the CORE routines is not very friendly.
The aim of my test was to improve paint times, but I found that when I tried to paint by lines, rather than points the paint times were then less significant than compared to other graphics functions I was doing, such as generating the image and even allocating and initialising the arrays.
John |
|
Back to top |
|
|
johannes
Joined: 21 Jan 2011 Posts: 65 Location: Leimen, Germany
|
Posted: Thu Aug 28, 2014 3:39 pm Post subject: |
|
|
Hi John, Paul, Wilfried,
I adapted Wilfried's code and tried with latest 7.10 and 6.30. Both create the jpg file but none of them the .png (i=0).
I compiled john's code from below and confirm that no .png is created with 6.30 and 7.10.
Now I am also confused about the version discussion. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Aug 28, 2014 4:07 pm Post subject: |
|
|
I am using FTN95/Win32 Ver. 7.00.0. Perhaps Paul could test the latest version I posted, as it works with my .dll dated 18-Dec-2013.
I have not yet tried Ver 7.1, so would be interested to find out if this is a regression.
John
PS: Well I just installed version 7.10.0 dated 27-Apr-14 over Ver 7.00 and it produces a .png file. I am not sure what is different. ( my OS is Windows 7 Home Premium. The latest version I tested is: Code: | winapp
program test3
implicit none
include <windows.ins>
integer*4 i,j,A,lins,cols
integer*4 x,y, HANDLE
real*8 r
character*1, dimension(:,:,:), allocatable :: image
character*1 :: red(3), blue(3), black(3)
! create 24-bit test image (replace by your own)
handle = 4
lins = 250
cols = 550
allocate ( image(3,cols,lins) )
!
red = char(1) ; red(1) = char(255)
blue = char(1) ; blue(3) = char(255)
black = char(1)
!
image = char(255) ! white
do y = 1,lins
image(:,1,y) = red
image(:,cols,y) = red
end do
do x = 1,cols
image(:,x,1) = blue
image(:,x,lins) = blue
end do
!
do y = 2,lins-1
do x = 2,cols-1
if (mod(y,50) .eq. 0 .or. mod(x,50) .eq. 0) image(:,x,y) = black
end do
end do
! off-screen graphics & export
j = create_graphics_region@ (handle,cols,lins)
j = select_graphics_object@ (handle)
!
call display_dib_block@ (0,0,image,cols,lins,0,0,cols,lins,0,0,i)
!
r = set_jpeg_quality@ (1.D0)
j = export_image@ ('c:\temp\test_71.jpg') ! works
j = export_image@ ('c:\temp\test_71.bmp') ! works
j = export_image@ ('c:\temp\test_71.gif') ! works
j = export_image@ ('c:\temp\test_71.png') ! does not work !!
j = delete_graphics_region@ (handle)
!
end |
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Thu Aug 28, 2014 5:06 pm Post subject: |
|
|
Wilfried's program runs OK for me. |
|
Back to top |
|
|
johannes
Joined: 21 Jan 2011 Posts: 65 Location: Leimen, Germany
|
Posted: Thu Aug 28, 2014 7:29 pm Post subject: |
|
|
Hi Paul,
I compiled Wilfried's original code ( Thu Aug 28, 2014 1:14 pm ) using version 7.10 and as well my own application according to Wilfried's receipe.
.png is created ! ... before I copied the new salflibc.dll into my exe directory. Perhaps the initial bug was using a wrong dll.
Thanks a lot to all contributors! Helped a lot.
johannes |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|