Here is the first attempt at this.
Saving the images:
The below program will save all images (.bmp, .jpg, .gif, .png) that are in the .\images subdirectory.
You will need to create the sub-folder and copy all your images to that folder.
They will first be loaded and displayed on the screen.
The screen will then be scanned using calls to GetPixel and a 2-dimensional array will be created.
The array will then be converted to a binary string using Var2Bin.
The binary string will then be saved to IMAGE.DBF in a binary field.
Playing back the images:
The below program will display all the images that are in IMAGE.DBF.
They will first be converted from a binary string to a 2-dimensional array.
The screen will then be painted from the contents of the array.
The array can be manipulated with your own code either before saving or after restoring from the database.
I hope that this starts you in the direction you wish to be heading.
Code: Select all
#INCLUDE "dcdialog.CH"
#INCLUDE "appevent.CH"
#INCLUDE "dll.CH"
STATIC snHDll
FUNCTION Main()
LOCAL GetList[0]
DC_LoadRdds()
@ 0,0 DCPUSHBUTTON CAPTION 'Create Images and save to Image.Dbf' SIZE 70,2 ;
ACTION {||CreateImages()} FONT '12.Lucida Console'
@ 3,0 DCPUSHBUTTON CAPTION 'Playback Images that are stored in Image.Dbf' SIZE 70,2 ;
ACTION {||PlaybackImages()} FONT '12.Lucida Console'
DCREAD GUI FIT TITLE 'Make a choice'
RETURN nil
* ----------
FUNCTION CreateImages()
LOCAL GetList[0], oStatic, oBitmap, aImages, i, hDC1, aPixel
aImages := Directory('.\images\*.*')
FOR i := 1 TO Len(aImages)
oBitmap := DC_GetBitmap('.\images\'+aImages[i,1])
@ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP ;
CAPTION oBitmap PREEVAL {|o|o:autoSize := .t.} ;
EVAL {|o|hDC1 := GetWindowDC(o:getHWnd()), ;
aPixel := Array(o:caption:xSize,o:caption:ySize)}
DCREAD GUI FIT TITLE aImages[i] ;
EVAL {|o|LoadArray(hDC1,aPixel), ;
Save2Dbf(aPixel,aImages[i,1]), ;
PostAppEvent(xbeP_Close,,,o)}
NEXT
RETURN nil
* ---------
PROC appsys ; RETURN
* ---------
FUNCTION LoadArray( hDC1, aPixel )
LOCAL i, j, oScrn, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
IF !aPixel[1,1] == nil
DCMSGBOX 'Array is already loaded!'
RETURN nil
ENDIF
oScrn := DC_WaitOn()
FOR i := 1 TO nXSize
FOR j := 1 TO nYSize
aPixel[i,j] := GetPixel(hDC1,i-1,j-1)
NEXT
NEXT
DC_Impl(oScrn)
RETURN nil
* ----------
FUNCTION Save2Dbf( aArray, cImage )
LOCAL cArray := Var2Bin(aArray)
USE image VIA 'FOXCDX' EXCLUSIVE
LOCATE FOR Trim(IMAGE->image_name) == cImage
IF Eof()
dbAppend()
REPLACE IMAGE->image_name WITH cImage, ;
IMage->array WITH cArray
ENDIF
IMAGE->(dbCloseArea())
RETURN nil
* ----------
FUNCTION PlaybackImages()
LOCAL aPixel, hDC1, GetList[0]
USE Image VIA 'FOXCDX' EXCLUSIVE
DO WHILE !IMAGE->(Eof())
aPixel := Bin2Var(IMAGE->array)
@ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP ;
COLOR nil, GRA_CLR_PALEGRAY ;
SIZE Len(aPixel), Len(aPixel[1]) PIXEL ;
EVAL {|o|hDC1 := GetWindowDC(o:getHWnd())}
DCREAD GUI FIT TITLE IMAGE->image_name ;
EVAL {|o|TransferImage(hDC1, aPixel), ;
Sleep(200), ;
PostAppEvent(xbeP_Close,,,o)}
IMAGE->(dbSkip())
ENDDO
RETURN nil
* ----------
FUNCTION TransferImage( hDC1, aPixel )
LOCAL i, j, lEmptyArray := aPixel[1,1] == nil, ;
nXSize := Len(aPixel), nYSize := Len(aPixel[1])
FOR i := 0 TO nXSize-1
FOR j := 0 TO nYSize-1
SetPixel(hDC1,i,j,aPixel[i+1,j+1])
NEXT
NEXT
RETURN nil
* ----------
#command GDIFUNCTION <Func>([<x,...>]) ;
=> ;
FUNCTION <Func>([<x>]);;
STATIC scHCall := nil ;;
IF scHCall == nil ;;
IF snHdll == nil ;;
snHDll := DllLoad('GDI32.DLL') ;;
ENDIF ;;
scHCall := DllPrepareCall(snHDll,DLL_STDCALL,<(Func)>) ;;
ENDIF ;;
RETURN DllExecuteCall(scHCall,<x>)
GDIFUNCTION GetPixel( nHDC, x, y)
GDIFUNCTION SetPixel( nHDC, x, y, n )
DLLFUNCTION GetWindowDC( hwnd ) USING STDCALL FROM USER32.DLL