Generating and saving images of characters

This forum is for eXpress++ general support.
Message
Author
User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Generating and saving images of characters

#31 Post by Auge_Ohr »

Eugene Lutsenko wrote:Now your program is compiled and running. But I did not understand what she was doing.
it only compare Speed of Xbase++ GraQueryTextBox() vs. API GetTextExtentPoint32() which is much faster.

Question : how long does it take to generate a complete Font-Set and how big (Pixel) are saved Bitmaps ?
greetings by OHR
Jimmy

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Generating and saving images of characters

#32 Post by Auge_Ohr »

rdonnay wrote:Are you taking over this project?
If so, I won't spend any more time on it.
No ... not real ... i still do not understand what Eugene want to do ... :think:
greetings by OHR
Jimmy

User avatar
rdonnay
Site Admin
Posts: 4813
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Generating and saving images of characters

#33 Post by rdonnay »

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
Attachments
image.zip
(1.97 KiB) Downloaded 589 times
The eXpress train is coming - and it has more cars.

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Generating and saving images of characters

#34 Post by Auge_Ohr »

i have read your Code how to store Array to BLOB and back to Array to Display in a Slideshow. this i understood.

what i mean : what is this good for ... ? why not store Bitmap into BLOB ? (same Result on Screen)

as i ask Eugene : how long does it take to process each Image and what is Image Size ?

when using "real" Image which Size might be much bigger it will take more Time to process his Code (FOR/NEXT) with Xbase++ and DllCall ...
also remember FOXDBE (DATA-Komponente) Memo is limited to 2^31 Bytes (2 Gigabyte)

i don't think Eugene just want to decode Bitmap Format ... but what else ?
i just can think on GIS ( Geographic Information Systems ) which use rasters that encode geographic data in the pixel values as well as the pixel locations.

p.s. Sunrise begin ...
greetings by OHR
Jimmy

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Generating and saving images of characters

#35 Post by Eugene Lutsenko »

rdonnay wrote:I guess you didn't understand what I meant by ZIP. I meant an archive file. RAR.
I'm not asking you to mail me anything.
Hi, Roger!

Last time I did not know and not think that there is a fundamental difference between zip and rar. He could not understand why the letter did not pass. Now, I understand that there is a difference.
rdonnay wrote: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.
Now, about your decision of my problem. I've studied and tested your program, Roger. This is exactly what I need! Thank you very much! I do everything completely satisfied and enjoy! Now I can move forward in implementing their plans.

As for the duration of the treatment, but now it does not matter to me. I'm not trying to get animations. Very large images in geographic information systems, too, is not going to handle. Other settlements in the Eidos, which I develop, also sometimes take a long time. If in the future will need to dramatically speed up the image processing, it will be possible to think about changing the implementation of certain functions.

User avatar
rdonnay
Site Admin
Posts: 4813
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Generating and saving images of characters

#36 Post by rdonnay »

what i mean : what is this good for ... ? why not store Bitmap into BLOB ? (same Result on Screen)
Eugene needed the pixel information in a 2-dimensional array that stores RGB colors as array elements.
He finds that it is easier to manipulate the data in an array that is representative of the image. I would tend to agree. Tweaking a color of a pixel would be simple.

Example:

Pixel 234/456 would be represented as aPixel[234,456].
The color would be a 3-element array.

aColor := aPixel[234,456]

aColor[1] += 10
aColor[2] += 10
aColor[3] += 10

This can be done before saving the array or restoring the array from the database. The image can then be repainted with TransferImage() or it can be saved to the database.
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Generating and saving images of characters

#37 Post by Eugene Lutsenko »

Thanks. Approximately so I thought. I'll deal with it yet. But now I have a full blockage and time pressure at work. At the same time I am July 12 release.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Generating and saving images of characters

#38 Post by Eugene Lutsenko »

Hello, Roger!

Include your development in Eidos. Everything works. But I do have questions.

Why do you use: "USE Image VIA 'FOXCDX' EXCLUSIVE", rather than "USE Image EXCLUSIVE"?

How to create a database "Image.dbf" standard FoxPro using the function: DbCreate()?

I tried to create a database Images.dbf (DBFNTX) using this function:

Code: Select all

FUNCTION GenDBFImage()

   CLOSE ALL

   ********* Создать БД Image.dbf и ее индексные массивы
   cFileName  := "Image.dbf"
   aStructure := { { "Image_name", "C", 250, 0 },;
                   { "Array"     , "M",  10, 0 } }
   DbCreate( cFileName, aStructure )

   LB_Warning('База изображений "Image.Dbf" создана!', "Оцифровка изображений по всем пикселям" )

RETURN nil
[/size]But then the function Bin2Var () why something is not working.

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Generating and saving images of characters

#39 Post by Auge_Ohr »

Eugene Lutsenko wrote:How to create a database "Image.dbf" standard FoxPro using the function: DbCreate()?
1.) write your own PROCEDURE dbeSys() and add FOX Support based on c:\ALASKA\XPPW32\Source\SYS\DbeSys.prg

Code: Select all

   IF !DbeLoad( "CDXDBE", .T. )
      ALERT( "Database-Engine CDXDBE nicht geladen", { "OK" } )
   ENDIF
   IF !DbeLoad( "FOXDBE", .T. )
      ALERT( "Database-Engine FOXDBE nicht geladen", { "OK" } )
   ENDIF
   IF !DbeBuild( "FOXCDX", "FOXDBE", "CDXDBE" )
      ALERT( "FOXCDX Database-Engine;konnte nicht erzeugt werden", { "OK" } )
   ENDIF
2.) Create VIA "FOXCDX"

Code: Select all

 DbCreate( "Image", aStructure, "FOXCDX" )
greetings by OHR
Jimmy

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Generating and saving images of characters

#40 Post by Eugene Lutsenko »

Thank you, Jimmy!

You're a very sympathetic person. Now everything works and then re-create the database. I'm talking about is revered in the documentation and Help, but for some reason there was an example of how the function should look DbCreate() in this case.

Post Reply