|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Fri Oct 17, 2014 6:28 am Post subject: |
|
|
Just a small remark to the source code before: The construction to get the full number of digits (leading zeros)
Code: | write(file_name(7:9),'(I3)')k
if (file_name(7:7).eq.' ') file_name(7:7)='0'
if (file_name(8:8).eq.' ') file_name(8:8)='0' |
can be simplified by
Code: | write(file_name(7:9),'(I3.3)')k |
Wilfried |
|
Back to top |
|
|
EKruck
Joined: 09 Jan 2010 Posts: 224 Location: Aalen, Germany
|
Posted: Mon Oct 20, 2014 8:45 am Post subject: |
|
|
Wonderful; it's really working.
Thanks Eddie and Dan !
Erwin |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Mon Oct 20, 2014 9:52 am Post subject: |
|
|
Erwin,
I try not to take credit for other people's work: in this case instead of me you owe credit to the late John Horspool and the guy at Silverfrost who wrote the 'Teapots' example (and Dan).
As you asked for GIF originally, and our examples to BMP (with JPG also supported according to the documentation), then please let us know if you succeed in getting the image in other formats with Clearwin+, and onto the clipboard (and how!).
Then, maybe Paul will implement the approach as standard routines in the Clearwin+ library.
Eddie |
|
Back to top |
|
|
EKruck
Joined: 09 Jan 2010 Posts: 224 Location: Aalen, Germany
|
Posted: Mon Oct 20, 2014 2:15 pm Post subject: |
|
|
I tried hard to create my GIF file, but up to now without success.
Code: | CALL Put_DIB_Block@ (BMP_FileName, ImageDIB, iSizeX, iSizeY, 0, 0, iSizeX, iSizeY, 24, iErr)
iBMP_Handle = Import_BMP@ (BMP_FileName, iErr)
CALL EXPORT_GIF@ (iBMP_Handle, '3dView_Graph.gif', iErr) |
After creating the BMP file I read it again with import_bmp@. I received a handle and error code zero.
export_gif@ however, returns error code 11 ?
All other trials e.g. with %gr and dib_paint@, select_graphics_object@ and export_image@ failed as well.
What else can I try?
Erwin |
|
Back to top |
|
|
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Mon Oct 20, 2014 4:10 pm Post subject: |
|
|
Erwin, this "workaround" may help - at least, it works with several BMP images I used for testing:
Code: | winapp
program test
implicit none
include <windows.ins>
integer*4 i,hdl,rows,cols,bit,rtcode
call get_dib_size@('graphics.bmp',cols,rows,bit,rtcode)
hdl = import_bmp@('graphics.bmp',rtcode)
i = create_graphics_region@(2L,cols,rows)
i = select_graphics_object@(2L)
i = dib_paint@(0,0,hdl,0,0)
i = export_image@('graphics.gif')
i = delete_graphics_region@(2L)
end |
Wilfried |
|
Back to top |
|
|
EKruck
Joined: 09 Jan 2010 Posts: 224 Location: Aalen, Germany
|
Posted: Tue Oct 21, 2014 8:18 am Post subject: |
|
|
Thanks Wilfried,
now it's perfect! Here my final source code.
Code: |
INTEGER FUNCTION SaveOpenGL_Bitmap ()
IMPLICIT NONE
INCLUDE <clearwin.ins>
INCLUDE <opengl.ins>
CHARACTER GIF_FileName*64
GIF_FileName = 'Graphics.gif'
CALL OpenGL_To_GIF (GIF_FileName)
SaveOpengl_Bitmap = 2
RETURN
END FUNCTION SaveOpenGL_Bitmap
SUBROUTINE OpenGL_To_GIF (GIF_FileName)
IMPLICIT NONE
INCLUDE <clearwin.ins>
INCLUDE <opengl.ins>
CHARACTER GIF_FileName*(*)
INTEGER I, J, K, iSizeX, iSizeY, iBit, iErr, iBMP_Handle, Koff, Kount, MA
CHARACTER*1, ALLOCATABLE :: ImageData(:)
CHARACTER*1, ALLOCATABLE :: ImageDIB(:,:,:)
CHARACTER BMP_FileName*32
LOGICAL EXI
iSizeX = clearwin_info@ ('OPENGL_WIDTH')
iSizeY = clearwin_info@ ('OPENGL_DEPTH')
ALLOCATE (ImageData(3*(iSizeX+3)*iSizeY))
ALLOCATE (ImageDIB(3,iSizeX,iSizeY))
ImageData = ' '
ImageDIB = ' '
CALL glReadPixels (0, 0, iSizeX, iSizeY, GL_RGB, GL_UNSIGNED_BYTE, ImageData)
Koff = mod (iSizeX, 4)
Kount = 0
DO J= 1, iSizeY
DO I= 1, iSizeX
DO K= 1, 3
Kount = Kount + 1
ImageDIB(K, I, iSizeY-J+1) = ImageData(Kount)
ENDDO
ENDDO
Kount = Kount + Koff
ENDDO
BMP_FileName = 'OpenglTemp37168.bmp'
INQUIRE (FILE= BMP_FileName, EXIST= EXI)
IF (EXI) CALL ERASE@ (BMP_FileName, iErr)
CALL Put_DIB_Block@ (BMP_FileName, ImageDIB, iSizeX, iSizeY, 0, 0, iSizeX, iSizeY, 24, iErr)
CALL Get_DIB_Size@ (BMP_FileName, iSizeX, iSizeY, iBit, iErr)
iBMP_Handle = Import_BMP@ (BMP_FileName, iErr)
MA = Create_Graphics_Region@ (2L, iSizeX, iSizeY)
MA = Select_Graphics_Object@ (2L)
MA = DIB_Paint@ (0, 0, iBMP_Handle, 0, 0)
MA = Export_Image@ (GIF_FileName)
MA = Delete_Graphics_Region@ (2L)
MA = MA
CALL ERASE@ (BMP_FileName, iErr)
RETURN
END SUBROUTINE OpenGL_To_GIF
|
Of course, the GIF_FileName has to be set individually.
Erwin |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Tue Oct 21, 2014 11:50 am Post subject: |
|
|
MA=MA?
I suspect that with all the error codes and function return codes, you will need a lot of extra code to handle all possible error conditions and exit gracefully!
Can I suggest using TEMP_FILE@ and SET_SUFFIX@ (See the FTN77 library) to give you a unique temporary BMP filename?
Eddie |
|
Back to top |
|
|
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Tue Oct 21, 2014 4:38 pm Post subject: |
|
|
I made a few more tests to convert BMP to GIF and I found a funny behaviour of the export_gif function. Maybe this is of interest for Paul?
Code: | winapp
program test
implicit none
c_external bmp_imp '__import_bmp'(STRING,REF) : integer*4
c_external gif_exp '__export_gif'(VAL,STRING,REF)
integer*4 hdl,rtcode
character*256 file
file = 'graphics.bmp'//char(0)
hdl = bmp_imp(file,rtcode)
file = 'graphics.gif'//char(0)
call gif_exp(hdl,file,rtcode)
end
|
Results:
(1) Sometimes gif_exp returns 11 like previously reported by Erwin. The output file is created but empty.
(2) Sometimes the program breaks down (for instance this happened with some 8-bit grey-scale BMPs)
(3) Sometimes it works perfectly (!!), the GIF is created.
Regards - Wilfried |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Oct 22, 2014 8:25 am Post subject: |
|
|
I keep forgetting what I can and can't do with Device Independent Bitmaps. Having both array and handle addresses is confusing, while they don't appear to be easily related.
Erwin's approach looks to work, but why do we need to create a temporary .bmp file ?
His approach is:
Get the size of the Opengl image
Create a DIB array for that size
Interrogate the Opengl region and populate the ImageDIB
export ImageDIB to a .bmp file with Put_DIB_Block@
Interrogate the .bmp file to get it's size
Import the .bmp file to a DIB handle using Import_BMP@
Create a graphics region of the same size with Create_Graphics_Region@
select this graphics region with Select_Graphics_Object@
copy the DIB handle to this graphics region with DIB_Paint@
export the graphics region to file using Export_Image@
Tidy up all the left overs.
Why can't we copy the DIB array direct to the Graphics region ?
Export_Image@ is now very flexible as it supports .png, .jpg, .jpeg, .bmp, .gif, .emf, and .pcx.
An alternative may be to not use DIB routines at all, but a temporary RGB_colour_array then "paint" it to the new selected graphics object using:
Get the size of the Opengl image
Create an array for that size to store the pixel values.
Interrogate the Opengl region and populate the colour array
Create a graphics region of the same size with Create_Graphics_Region@
select this graphics region with Select_Graphics_Object@
Populate the graphics region with either Draw_Point@ or Draw_Line_Between@, scanning each horizontal line where the same colour is repeated.
export the graphics region to file using Export_Image@
Tidy up all the left overs.
I have found Draw_Line_Between to be an efficient approach where only a small colour palette is used. With a 1920x1080 resolution image, this is 2 million calls to Draw_Point, which was once quite slow. You need to test.
This is the approach I have used for my "hidden line removal" approach, where I keep a colour array(horz,vert) as character*1 colour index (255 colours) and depth array(horz,vert) as a real*4 active depth of each pixel. When complete, I paint this array to the selected graphics object (%gr or virtual) then direct to .png file. ( I support up to 3072 x 2304 virtual image which is 35 mb for me to store )
I would expect the temporary array is needed as it may be difficult (inefficient) to switch between the opengl region and the Select_Graphics_Object as an active region.
Anyone tried these alternatives ?
John |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Wed Oct 22, 2014 1:44 pm Post subject: |
|
|
John,
The approaches given do work, but may not be the most efficient. I'd like to see a working version of your proposal for comparison of run times. The intermediate bitmap step does seem to be ridiculous, I agree. However, it mainly uses existing Clearwin+ routines that require little knowledge of the structure of any particular format.
I think that for a limited palette, OpenGL (%og) is over-complicated relative to %gr, but often OpenGL is used because of complicated shading, in which case the palette won't be small - simple graphics with a few areas of solid colour, lines and text are very easy with %gr.
Eddie |
|
Back to top |
|
|
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Wed Oct 22, 2014 3:47 pm Post subject: |
|
|
The following code shows the problem. First, a 24-bits image (800 x 600 pixels) is created and saved as BMP, you can control this with any image viewer. Then, this BMP is imported by import_bmp and should be exported with export_gif. As far as I found out unto now, export_gif cannot handle 24-bits images:
Code: | winapp
program test
implicit none
include <windows.ins>
integer*4 i,j,A
character*1 image(1450000)
character*256 ifile,ofile
c_external bmp_imp '__import_bmp'(STRING,REF) : integer*4
c_external gif_exp '__export_gif'(VAL,STRING,REF)
ifile = 'test.bmp'//char(0)
ofile = 'test.gif'//char(0)
c create 24-bits test image
do i = 1,600
A = (i-1)*2400
do j = 1,2400,3
image(A+j ) = char(mod(j,255))
image(A+j+1) = char(mod(i,255))
image(A+j+2) = char(mod(i+j,255))
end do
end do
c off-screen graphics & export to BMP
j = create_graphics_region@(4L,800L,600L)
j = select_graphics_object@(4L)
call display_dib_block@(0,0,image,800L,600L,0,0,800L,600L,0,0,i)
if (i == 0) j = export_image@(ifile)
j = delete_graphics_region@(4L)
c import of BMP and export to GIF
A = bmp_imp(ifile,i)
if (i == 0) call gif_exp(A,ofile,i) !! here the program failes
end |
Wilfried |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2819 Location: South Pole, Antarctica
|
Posted: Wed Oct 22, 2014 10:31 pm Post subject: |
|
|
Wilfried, i'd also add the deallocate to your first code |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Oct 22, 2014 11:28 pm Post subject: |
|
|
Wilfred,
.gif uses a fixed 256 colour palette. It chooses the "closest" colour to it's available palette.
To overcome this .png format can be used, which is what I lobbied for.
Just replace .gif with .png and you will see an improvement. I now use .png for all my graphics dumps.
.gif is suitable when there are only a few colours, as the resulting file is very compact.
Eddie may have a valid point, that opengl may use a very large palette of colours, which would need to be stored as RGB in the temporary array.
DIB could be much more useable if there were a few basic routines to allow transfer between DIB arrays, DIB handles and Graphics_Objects.
John |
|
Back to top |
|
|
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: Düsseldorf, Germany
|
Posted: Thu Oct 23, 2014 2:19 pm Post subject: |
|
|
Dan and John,
I don't use GIF in my own software (only BMP, JPEG and TIFF). I only had a little bit of time yesterday and tried to find out why the export_gif function has that funny behaviour.
In my software I use functions from a friend of mine, written in C, and also sometimes parts of the FreeImage library.
Wilfried |
|
Back to top |
|
|
EKruck
Joined: 09 Jan 2010 Posts: 224 Location: Aalen, Germany
|
Posted: Thu Oct 23, 2014 3:34 pm Post subject: |
|
|
My line graphics have about 20 to 30 different colors. Therefor GIF-files are perfect.
I extended my subroutine a little between DIB_Paint@ and Delete_Graphics_Region@ to allow a copy of the graphics to the paste buffer, and found a curious situation:
Code: |
MA = DIB_Paint@ (0, 0, iBMP_Handle, 0, 0)
CALL DRAW_RECTANGLE@ (4, 4, iSizeX-5, iSizeY-5, RGB@( 84,252, 84))
IF (GIF_FileName .EQ. ' ') THEN
MA = GRAPHICS_TO_CLIPBOARD@ (0, 0, iSizeX-1, iSizeY-1)
ELSE
MA = Export_Image@ (GIF_FileName)
ENDIF
MA = Delete_Graphics_Region@ (2L)
|
DRAW_RECTANGLE@ creates a box with distance of four pixels from all edges. The graphic file from Export_Image@ is correct; for the paste buffer I have to use the parameters above to have a correct image in the buffer !?
A bug?
Erwin |
|
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
|