|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
silicondale
Joined: 15 Mar 2007 Posts: 252 Location: Matlock, Derbyshire, UK
|
Posted: Tue Aug 20, 2013 8:34 am Post subject: IMPORT_BMP@ - equivalents for JPG, GIF, PNG ? |
|
|
I have an application which works just fine with IMPORT_BMP@ and IMPORT_PCX@ to import images bigger than the %gr window, and then scroll (using %vs, %hs) to view the parts that are not displayed. I would really like to do the same with JPG and GIF files, but there don't seem to be equivalent subroutines IMPORT_JPG@ or IMPORT_GIF@.
I know there is IMPORT_IMAGE@ which should import any of these graphic formats, but if I use this the scrolling doesn't work. Are there any example programs that show how I can use this to import images bigger than the window and then scroll to see the undisplayed parts?
I could of course use GET_DIB_BLOCK@ but if I understand correctly this supports only BMP and JPG, not GIF or PCX. I think it also would need major re-writing of the program, which I'd rather not do!
For any of the solutions, it would be very helpful if they also supported PNG format.
The purpose of the application is on-screen digitising - e.g. tracing over features in a photo to record geological boundaries. The photos are usually high resolution, hence the need for scrolling. |
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Tue Aug 20, 2013 9:13 am Post subject: Re: IMPORT_BMP@ - equivalents for JPG, GIF, PNG ? |
|
|
silicondale wrote: |
I know there is IMPORT_IMAGE@ which should import any of these graphic formats, but if I use this the scrolling doesn't work. Are there any example programs that show how I can use this to import images bigger than the window and then scroll to see the undisplayed parts?
|
It goes something like this...
1. Create a off-screen %gr graphics surface using CREATE_GRAPHICS_REGION@()
2. Select the off-screen graphics surface using SELECT_GRAPHICS_OBJECT@()
3. Import the image into the off-screen graphics surface using IMPORT_IMAGE@()
4. Select the original %gr graphics surface back using SELECT_GRAPHICS_OBJECT@()
5. Draw the portion of the image you want into the %gr graphics surface using COPY_GRAPHICS_REGION@()
Here is an old example project. |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 252 Location: Matlock, Derbyshire, UK
|
Posted: Tue Aug 20, 2013 9:25 am Post subject: |
|
|
Jalih - Once again, you're an absolute star!! Will try this and report back, but I'm confident your solution is the way to go, with minimum hassle.
.... tried it, and with a bit of adjustment it now works well! Many thanks. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2390 Location: Yateley, Hants, UK
|
Posted: Wed Aug 21, 2013 10:20 am Post subject: |
|
|
Jalih, as always, has a solution that reflects the epitome of computer science. I thought yesterday that there might be a simpler answer, and wasted a whole evening, as well as learning something.
My solution was to simply reimport the image with different offsets: viz:
Code: | WINAPP
OPTIONS (INTL, DREAL)
PROGRAM SCROLL
COMMON /GRAPHICS/ iXRES, IYRES, iHANDLE, N
INCLUDE <WINDOWS.INS>
INTEGER, EXTERNAL :: MOVEPHOTO
IXRES=300; IYRES = 200; iHANDLE = 99; N = -1
IA=WINIO@('%ca[TRIAL by shifting]&')
IA=WINIO@('%sc&', MOVEPHOTO)
IA=WINIO@('%`^gr[BLACK]&', IXRES, IYRES,
& iHANDLE, MOVEPHOTO)
IA=WINIO@('%ff%nl%rj%12^bt[Shift NW]', MOVEPHOTO)
STOP; END
INTEGER FUNCTION MOVEPHOTO()
COMMON /GRAPHICS/ iXRES, IYRES, iHANDLE, N
INCLUDE <WINDOWS.INS>
MOVEPHOTO = 1
CALL DRAW_FILLED_RECTANGLE@ (0,0,IXRES,IYRES,RGB@(0,0,0))
N = MIN(N + 1, 30)
CALL IMPORT_IMAGE@ ('CAT', -N*10, -N*10)
RETURN; END
RESOURCES
CAT IMAGE "9845A.JPG" |
What did I discover? Well, the first thing was that the photo of my cat was either too large, or in an unacceptable JPEG format. Instead of a meaningful error message, I was left with a runtime error bleating about a missing GIF file. The second thing is that if you don't use these IMPORT routines frequently, you forget the niceties of whether they are FUNCTION or SUBROUTINE, and precisely what needs to be in quote marks. I ended up with a much smaller JPEG of an old computer, and movement only up-and-left together (just to show it worked with negative offsets) - and it does, but there are critical "gotchas", like if you scroll it off the visible area, and if you don't wipe the %gr each time.
I imagine that if the image is a RESOURCE, then this is as quick as Jalih's solution, but if the file needs to be re-read each time, then it will be painfully slow.
Now where is that definition of hubris?
Eddie |
|
Back to top |
|
|
silicondale
Joined: 15 Mar 2007 Posts: 252 Location: Matlock, Derbyshire, UK
|
Posted: Wed Aug 21, 2013 10:49 am Post subject: |
|
|
Hi Eddie - I'm really sorry to have been the cause of so much pain! I guess the original problem was my lack of understanding that IMPORT_BMP@ (and IMPORT_PCX@) work in a basically different way to IMPORT_IMAGE@, which seems to be a much newer and more logical approach. What I'm stuck with currently is a program which works fine with IMPORT_BMP@ for BMP files, and also works fine with IMPORT_IMAGE@ for JPG and GIF, but with different sets of code for scrolling. Both image formats work fine, but not sure if I have the courage to cut the safety wire, simplify my coding, and use IMPORT_IMAGE@ for everything!
I think also that I need to read the manual again because in another part of the system I'm using DIB_BLOCK coding for generating and exporting graphics, with an explicitly declared array holding all the pixels. But I'm not at all sure how this relates to the graphics surface used by IMPORT_IMAGE@
By the way, I'm not using a RESOURCE to define the image file, but the curly bracket filename '{xxxx.jpg}' because the file is selected at runtime. I construct the curly bracket character variable from the pathname returned by GET_FILTERED_FILE@. Slowly (re)learning the tricks. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Tue Sep 17, 2013 6:30 am Post subject: |
|
|
Norm's post on a related thread has prompted me to look at this problem of importing files. I have this need so that I can export them in an alternative format, especially my old .pcx files that are no longer supported by Microsoft Word.
There are a number of graphics file formats referenced in Clearwin+ including .jpg, .bmp, .gif, .pcx .emf and .png. ( any others ?)
Unfortunately Import_Image@ does not appear to support all formats and more importantly Get_DIB_Size@ or Get_IM_Info@ does not support getting size information on all formats. Am I wrong with this interpretation of Clearwin+ capability ?
What I am trying to do is to convert .jpg, .bmp, .gif or .pcx files to .png files. My preferred approach is to:
1) find the size of the files,
2) create a graphics region or DIB array
3) import the file
4) export the file to a .png file
I wanted to check:
if there was a problem with large files ( > 2048 pixel dimension ) or
if there is a restriction on the dimension, as a multiple/power of 2.
Can anyone help with a 2-dimensional matrix of the preferred clearwin+ routine to use for the above 4 actions for the 6+ graphics file formats ?
My testing today has thrown up a few unexpected errors, which are probably due to my lack of experience with Clearwin+.
What does the error "Curly bracket/integer form is not available in this context" mean ? Presumably it does not like the external file name in the WINAPI routine ?
John |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7933 Location: Salford, UK
|
Posted: Tue Sep 17, 2013 8:30 am Post subject: |
|
|
The error report seems quite clear. What does the code look like at this point? |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Wed Sep 18, 2013 1:02 am Post subject: |
|
|
Paul,
The error is with import_image@ where the file name is '{picture.jpg}'.
I think that there is a bit of variability in what is in the header of .jpg files, downloaded from cameras. My best estimate of the problem is the winapi does not like the format of the .jpg file header.
When I get time, I will try to identify how to import the different file formats. I have found the documentation of how to get the size of different file types a bit brief. It would be good if this could be summarised and include the graphics formats that are now supported.
I was surprised by the size of the resulting file when converting pictures from .jpg to .png. I still find .png format to be the prefered format for exporting charts, which I later import into reports.
John |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7933 Location: Salford, UK
|
Posted: Wed Sep 18, 2013 7:30 am Post subject: |
|
|
John
'{picture.jpg}' should work OK but not when the first character 'p' is a digit because, more generally. curly brackets can also be used with integer handles (for BITMAPs etc.). |
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Wed Sep 18, 2013 9:37 am Post subject: Re: |
|
|
JohnCampbell wrote: |
What I am trying to do is to convert .jpg, .bmp, .gif or .pcx files to .png files. My preferred approach is to:
1) find the size of the files,
2) create a graphics region or DIB array
3) import the file
4) export the file to a .png file
|
If you just need to convert graphics file into another graphics file format, then I would use GDI+ Flat API Image functions.
Simple demo project here
MiniBASIC source for the FTN95 callable image2png() function:
Code: |
##ifndef WIN32
##define WIN32
##endif
##ifdef WIN32
##define WIN32_LEAN_AND_MEAN
##endif
##include "winsdk\windef.mbi"
##include "winsdk\winbase.mbi"
##include "winsdk\wingdi.mbi"
##include "winsdk\winuser.mbi"
##NOCONSOLE
##MAKEDLL
##USES "gdiplus.lib"
type GdiplusStartupInput
int GdiplusVersion
int DebugEventCallback
int SuppressBackgroundThread
int SuppressExternalCodecs
endtype
typedef GpImage uint
@API GdiplusStartup(uint *token, GdiplusStartupInput *inp, GdiplusStartupOutput *outp),int
@API GdiplusShutdown(uint token)
@API GdipLoadImageFromFile(wstring filename, GpImage *image),int
@API GdipSaveImageToFile(GpImage *image, wstring filename, CLSID *clsidEncoder, EncoderParameters *encoderParams),int
@API GdipDisposeImage(uint image)
export image2png
func image2png(string source, string target),int
int result
gpImage *image = NULL
uint *token = NULL
GdiplusStartupInput gsi(1,NULL,FALSE,FALSE)
GUID pngClsid
DEFINE_GUID(pngClsid, 0x557cf406,0x1a04,0x11d3,0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e)
GdiplusStartup(&token,gsi,NULL)
result = GdipLoadImageFromFile(a2w(source),&image)
if result <> 0
GdiplusShutdown(token)
return FALSE
endif
result = GdipSaveImageToFile(image,a2w(target),&pngClsid,NULL)
GdipDisposeImage(image)
GdiplusShutdown(token)
if result <> 0 then return FALSE
return TRUE
endf
|
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Wed Sep 18, 2013 10:13 am Post subject: |
|
|
Jalih,
Thanks for the solution, but I wanted to do this with clearwin+ fortran calls.
I am trying to understand how to determine the size of a graphics file so that I can manage it in either a �drawing surface� or a �device independent bitmap� ( I think these are handled differently, or can their handles identify the difference ?)
Possible file formats .jpg, .bmp, .gif, .pcx .emf and .png
I don�t like the routine Import_image@ which works for .jpg, .bmp, .gif or .pcx; as it does not return the image size.
For .bmp, .gif or .pcx, the following routines could help, as they create a DIB block for the imported file, but how do you get the size of the returned DIB block?
Import_BMP@ : reads a .bmp file and creates a DIB handle
Import_gif@ : reads a .gif file and creates a DIB handle
Import_PCX@ : reads a .pcx file and returns a DIB handle
Does Get_Graphical_Resolution@ work after calling select_Graphics_Object@ for the DIB handle ?
Alternatively, Get_DIB_Size@ might return this information, but it is only documented to work with .bmp files.
As for .png files, all I can do is export them. Can they be imported ?
I am probably showing my limited understanding of Clearwin+ but is there a more general solution available in Clearwin+
John |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7933 Location: Salford, UK
|
Posted: Wed Sep 18, 2013 1:12 pm Post subject: |
|
|
1) import_image@ works for .bmp, .gif, .pcx, .jpg, and .png files.
2) get_im_info@ works for .bmp, .gif, and .pcx files (it needs extending so that it also works with .jpg and .png files)
3) get_dib_size@ works for .bmp, .gif, .pcx, and .jpg files.
4) There is an exported but undocumented function size_image that might give the dimensions of a png image but I have not tested it.
C_EXTERNAL SIZE_IMAGE 'size_image' (VAL, REF, REF)
SUBROUTINE SIZE_IMAGE(HANDLE, WIDTH, HEIGHT)
INTEGER HANDLE,WIDTH,HEIGHT
HANDLE is input as the Microsoft handle for the image.
WIDTH and HEIGHT are the output values.
Off hand I don't know how to get the input HANDLE.
I will make a note that get_im_info@ needs extending. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Thu Sep 19, 2013 2:25 am Post subject: |
|
|
Paul,
Hopefully I can keep this post brief !
I am trying to understand the difference between 3 file import routines and how the resulting memory image can be used.
import_image@ : To paste an image on to a (%gr) drawing surface using an internal resource or an external file. Presumably this copies to the current drawing surface, that was selected via SELECT_GRAPHICS_OBJECT@( HANDLE ). HANDLE is defined by the programmer.
get_dib_block@ : To read a BMP or JPEG format file into a character array, PARRAY. PARRAY is created using ALLOCATE and does not have a HANDLE.
import_gif@ : Reads in a GIF file and returns a DIB handle to the image. Presumably this routine creates the memory allocation, which can be released via RELEASE_SCREEN_DIB@( HDIB )
Based on an understanding that Get_Point@ and Draw_Point@ are inefficient, I have previously tried to use %gr[USER_SURFACE] to manipulate the graphics area via the returned memory address �ptr�. This works well for the %gr window, but I have had trouble addressing other drawing surfaces selected via SELECT_GRAPHICS_OBJECT@.
I am now looking at manipulating the graphics via a DIB array, but am confused by how these can have a returned HANDLE, but no PARRAY.
To overcome this, a possible way forward might be;
I need to know the dimension of this returned DIB (essential information)
Select this DIB using Select_Graphics_Object@, via it�;s returned HANDLE,
(alternatively use DIB_Paint@ (handle) to copy to the current drawing surface which has been created to the correct size. )
Create a PARRAY of the right size,
Use Recover_DIB_Block@ to obtain the image in PARRAY, so that I can manipulate the image for it�s full size.
There are essentially 4 different types of device independent bitmaps, which could be the same thing if �PTR�, �HANDLE� and PARRAY could be matched to the same location.
1) %gr, Create_Graphics_Region@ and import_image@ have a programmer supplied HANDLE value.
2) %gr[user_surface] has an array address �PTR� which is limited to the screen graphics surface.
3) Import_gif@ or Get_Screen_DIB@ have returned handles and returned memory.
4) Recover_DIB_Block@ and Display_DIB_Block@ transfer DIB between PARRAY and the current graphics device (is this the current drawing surface ?)
My expectation is that the current drawing surface is based on the image size and NOT the %gr window size. This can be created via Create_Graphics_Region@, if the handle or PARRAY can not be selected. I have successfully used drawing surfaces that are larger than %gr graphics device.
My main question is : Are there really 4 different image types in memory or are some interchangeable?
We need an up to date document which describes how to manage transferring information between these different ways of addressing images in memory and some indication of their efficiency.
John |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7933 Location: Salford, UK
|
Posted: Thu Sep 19, 2013 7:48 am Post subject: |
|
|
John
Thanks for the questions but frankly it would take me at least a working day to begin to find the answers. If you can find a way to reduce the task then I may be able to cope.
Paul |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Thu Sep 19, 2013 8:51 am Post subject: |
|
|
Paul,
I think I am identifying a need for some documentation of how to shift between different in-memory graphics models and also more general import/export support for standard formats.
The standard formats are possibly .bmp .pcx .jpg .gif and .png, although Steve may include .emf ( which is quite different). These need to be supported in a more documented way.
For file import/export we need either Export_JPG@ and Export_PNG@ or make Export_Image@ and Import_Image@ documented for all 5 formats.
(.jpg formats appear more difficult to use as there appears to be variability in their header structure. A warning of this might help)
We need to be able to interogate files or DIB handles for their size, as I can't see an easy way of getting this information. Get_DIB_Size@ or Get_IM_Size@ could be adapted for this ? ( Am I missing something, but I can't see how to get the size of a DIB Handle ? )
It would be good to have documentation or examples of moving between Create_Graphics_Region@, DIB_Handle or DIB_PARRAY formats.
Even identifying the difference between a programmer supplied handle and a returned handle would clarify a lot of problems I keep coming back to.
There must be a history for PARRAY and DIB_handle, as applying PARRAY to a DIB handle would be non-standard Fortran. Just having a guide on these and how to move between them woudl help.
If we could share a document, then perhaps a number of us could contribute to this document. I'd be pleased to help if we can find a way and a few of us have already commented on this post and have different experiences to share. Jalih, Steve, Eddie, Wilfred, Dan, Ian, Norm and others have all contributed to this recently and could help with their experience.
Over the years, I keep coming back to these issues and forget what I learnt the previous time.
The results could be included in the FTN95 documentation under:
Drawing device independent bitmaps
Off-screen graphics
Using image resources
Graphics functions (Device independent bitmaps)
All these could be enhanced to clarify the issues identified.
John |
|
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
|