How do you call SaveImage?

How do you call SaveImage?

I want to use the function SaveImage
It saves the image of a portion of the screen onto a Windows Bitmap.
That is just what I want and it appears to be very simple.

When I try

use Dflib

INTEGER*4		iret,ulx,uly,lrx,lry

ulx=0
uly=0
lrx=100
lry=100

iret=SaveImage ("c:	empitmap.bmp",ulx,uly,lrx,lry)

I get the following error message
error LNK2001: unresolved external symbol __f_saveimage@24

Any ideas what the problem is.

Thanks,

David

14 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Reading the documentation again I my problem is because it says :
STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

while my project is a Windoiws API project.

Therefore, how can I reproduce the functionality of SaveImage - Save an image from a specified portion of the screen into a Windows bitmap file - in a Windows API project?

Thanks,

David

David,
There's a pair of articles called "Capturing an Image" and "Storing an Image" in Bitmaps section of platform SDK.

My XFTGDI module contains simple wrappers for that. There, it should be as simple as:

TYPE(X_DC) xDC
TYPE(X_BITMAP)  xBmp
...
xDC%hDC = GetDC(NULL)
bret = XGetBitmap(xDC, xBmp, 23, 42, 368, 531)
bret = XSaveBitmap(xBmp, "Foo.bmp")
bret = XDeleteBitmap(xBmp)

Even if you don't use them as-is, you could take a look at the code. XSaveBitmap is based on "Storing an Image" article, but translation from C can get tricky at moments.

HTH
Jugoslav

Thanks,
I have taken your code and added XFLOGM.f90, XFTFile.90, XFTGdi.f90 & XStrings.f90 to my project.
When I compile I get lots of errors.
A few of them are shown below.
There must be something simple that I have missed out.

David

Error: Error in opening the Library module file. [XFTTYPES]
USE XFTTYPES
----^
XftGDI.f90(155) : Error: Error in opening the Library module file. [XFTAPI]
USE XFTAPI
----^
XftGDI.f90(279) : Error: This derived type name has not been declared. [T_POINT]
TYPE(T_POINT):: PT(2)
-----^
XftGDI.f90(296) : Error: This derived type name has not been declared. [X_DC]
TYPE (X_DC), INTENT(INOUT):: xDC
------^
XftGDI.f90(294) : Error: This name does not have a type, and must have an explicit type. [XDC]
SUBROUTINE XSetPen_1(xDC, iColor, iStyle, iWidth)
---------------------^
XftGDI.f90(319) : Error: This derived type name has not been declared. [X_DC]
TYPE (X_DC), INTENT(INOUT):: xDC
------^
XftGDI.f90(320) : Error: This derived type name has not been declared. [X_PEN]
TYPE (X_PEN), INTENT(IN):: xPen
------^
XftGDI.f90(317) : Error: This name does not have a type, and must have an explicit type. [XDC]
SUBROUTINE XSetPen_2(xDC, xPen)
---------------------^
XftGDI.f90(317) : Error: This name does not have a type, and must have an explicit type. [XPEN]
SUBROUTINE XSetPen_2(xDC, xPen)
--------------------------^
XftGDI.f90(330) : Error: This derived type name has not been declared. [X_DC]
TYPE (X_DC), INTENT(INOUT):: xDC
------^
XftGDI.f90(328) : Error: This name does not have a type, and must have an explicit type. [XDC]
SUBROUTINE XSetBrush_1(xDC, iColor, iStyle, iHatch)
-----------------------^
XftGDI.f90(354) : Error: This derived type name has not been declared. [X_DC]
TYPE (X_DC), INTENT(INOUT):: xDC
------^
XftGDI.f90(355) : Error: This derived type name has not been declared. [X_BRUSH]
TYPE (X_BRUSH), INTENT(IN):: xBrush

You have to !DEC$DEFINE XLITE either on tops of X*.f90 source files or in Project/Settings/Fortran/Preprocessor (it's defined in the latter place in the sample project).

Sorry for inconvenience, I should've stated it more clearly somewhere.

Jugoslav

Thanks once again. I don't know what the forum would do without you.

I just needed to add to the code you suggested

USE XFLOGM
USE DFWIN
USE XFTGDI

and it worked perfectly.

Now I have to decide if I should use it as it is or to take a look at the code!

Thanks,
David

The question isn't "What would we do without jugoslav?". It's what should we do for him. The amount of time he spends patiently educating this community is obvious. The amount of time his posts have saved me leave me wondering if there is anything (in addition to effusive praise) that we can offer.

Steve, how about a forum fellowship? Something to recognize the work involved to date and not intended to constitute employment.
If Intel doesn't have the marketing funds, perhaps you could host a PayPal payment link next to jugoslav's responses. I would happily pay a couple bucks every time a detailed response to a question saved me an hour.

At the very least add my thanks to David's.
Cheers, Cliff

Jugoslav's contributions here and elsewhere are valued by us and we have, in the past, expressed our appreciation to him in tangible fashion. I hope to continue doing so in the future.

Steve

Retired 12/31/2016

Is Jugoslav still using CVF 5.0D? If so, I'm willing to contribute toward buying him an upgrade to CVF 6.6 or IVF 8, whichever is more appropriate. Just tell me where to send my check.

I don't know how he does it, but Jugoslav knows one heck of a lot about Fortran and Windows. The kicker is that he generously shares his knowledge and time with others. He deserves real kudos.

Steve, you also are a great help to those of use using this forum, c.l.f, and elsewhere. Convince Intel to hire Jugoslav and the two of you can be the Batman and Robin of Fortran lore. Then go out and collaborate with Norman Lawrence on a new, expanded book.

Mike D.

My image is coloured lines drawn on a black background.

I would like to save this as black lines on a white background so I can paste it into a document.

I am wondering how do do this.

Looking at XGetBitMap there is a flag with various option, one of them may do this, I could try them all out and see if I can get the desired effect.

Or should I load the array of pixels and test the colour of each one and change the colours so I get the desired effect. How would I do this?

Thanks,
David

iDepth argument to XSaveBitmap, if set to 1, will give you 1-bit bitmap (i.e. black & white).

For allother, "smarter"conversions, you have to do it yourself. Basically, there are two methods:

1) Select the bitmap into a memory DC (XMemoryDC/XPlaceBitmap) and play with it. Effects such as masking and binary operations can be achieved using BitBlt (XBitCopy) and similar operations (take also a look at Ternary raster opertions in MSDN -- powerful but mind-boggling)

2) Play directly on bit array returned by GetDIBits (also powerful but mind-boggling) & set it back with SetDIBits. I didn't play with it. See also info on DIB Sections under Bitmaps chapter.

Jugoslav

Using the iDepth arguement of XSaveBitmap, I now have a bitmap with white lines on a black background. So I am half way there.

Before I start to look at XMemoryDC & XPlaceBitmap is there not an easier way to invert the image?

I have looked at XGetBitmap and flags DSTINVERT and NOTSRCCOPY look as if they do an invert, I've tried them but maybe I'm not calling them correctly. as I still get white lines on a black background.

David

Hmm, I performed a quick test and it gives the expected results:

xDesktop%hDC = GetDC(NULL)
iSt = XGetBitmap(xDesktop, xBmp, 0, 0, 1023, 767, iFlags=SRCCOPY)
iSt = XSaveBitmap(xBmp, "_Test.bmp", 1)
call ReleaseDC(NULL, xDesktop%hDC)

Gave screenshot withwhitebackgroundand black lines. NOTSRCCOPY produced an inverse.

Jugoslav

That works great. It was just my lack of experiance calling procedures with optional parameters.

Thanks,

David

Leave a Comment

Please sign in to add a comment. Not a member? Join today