Generating and saving images of characters

This forum is for eXpress++ general support.
Message
Author
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

#11 Post by rdonnay »

This will take some time to figure out what you want.

I have to finish another project that is close to deadline.
I will get to this in a few days.
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

#12 Post by Eugene Lutsenko »

rdonnay wrote:This will take some time to figure out what you want.

I have to finish another project that is close to deadline.
I will get to this in a few days.

I wish you success, Roger, in your project!

All problems boils down to answering the question. Is it possible to use the GetPixel() in the style of Roger with the images to create a standard way? If possible, everything else I can do. If not possible, then it is necessary to implement in the style of Roger image output without stopping.

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

#13 Post by Eugene Lutsenko »

That turned out a program that creates these images of characters specified font as needed:
http://lc.kubagro.ru/Dima/LC_GenFontsEng3.rar
Now I would like to apply a function by Roger

Code: Select all

mPix = GetPixel(hDC1, x-1, y-1)
to get information about the values of the pixels to create an image. Is it possible to do this given program or to somehow alter it, like Roger program, in which he gave examples of this feature.

I can call the window as shown in the example of Roger GetPixel(), with reference to the image file in a loop. However, to go to the next file, user interaction is required. In particular, the image processing functions themselves have to run using the buttons. And then you have to press Esc to go to the next step of the cycle. Therefore, I ask, can there be the option of using the function GetPixel() in conjunction with the traditional way of working with graphics, which is used in the above program.

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

#14 Post by rdonnay »

I need more clarification as to what you want.

Are you saying that you want to display images on the screen in a continuous loop with no user interaction and then save those images to a multi-dimensional array which is in turn saved to disk?

If this is true, then what is the source of the images?
Are they a bunch of files on disk?
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

#15 Post by Auge_Ohr »

hi,

i still do not understand what you want to do with GetPixel() and those Font ?
why you generate those (big) Font ... what do you want to do with it ?
when using a "big" Truetype Font you can use "every Size" ... but if you use Size bigger than "real" ( e.g. 72 Point ) it will be resize by Windows OS().
also Cleartype is default enable, which GraStringAt() use ( PDR 6314 ), so Pixel on Edge are "not real".

tell us the hole Story what you want todo ... else Answer may point into wrong Direction.


while GraQueryTextBox() is "slow" try this Sample from Günter Beyes.
it also show you how to use Windows API CreateFont()
GraQuery.zip
(8.66 KiB) Downloaded 605 times
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

#16 Post by Eugene Lutsenko »

rdonnay wrote:I need more clarification as to what you want.

Are you saying that you want to display images on the screen in a continuous loop with no user interaction and then save those images to a multi-dimensional array which is in turn saved to disk?

If this is true, then what is the source of the images?
Are they a bunch of files on disk?
Many thanks to you and in dialogue with you, I have already done:
http://lc.kubagro.ru/Dima/LC_GenFontsEng3.rar
Now I need to create arrays as a function LoadArray() from a wonderful example of Roger:

Code: Select all

STATIC snHdll

FUNCTION Main()

LOCAL GetList[0], GetOptions, oSay, hDC1, hDC2, oStatic1, oStatic2, ;
      aPixel

@ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP ;
      CAPTION "colors.bmp" ;
      OBJECT oStatic1 ;
      PREEVAL {|o|o:autoSize := .t.} ;
      EVAL {|o|hDC1 := GetWindowDC(o:getHWnd()), ;
               o:motion := {|a,b,o|ShowColor( hDC1, a, oSay, o )}, ;
               aPixel := Array(o:caption:xSize,o:caption:ySize)}

@ 0,250 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP;
      CAPTION "colors.bmp" ;
      PREEVAL {|o|o:autoSize := .t.} ;
      OBJECT oStatic2 ;
      EVAL {|o|hDC2 := GetWindowDC(o:getHWnd())}

*-------- DC

@ 50,0 DCSAY '' SAYSIZE 350,20 FONT '10.Lucida Console' OBJECT oSay

@ 100,0 DCPUSHBUTTON CAPTION 'Clear Image' SIZE 100,20 ACTION {||ClearImage(hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 10 DCPUSHBUTTON CAPTION 'Transfer Image' ;
    SIZE 80,20 ACTION {||TransferImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 10 DCPUSHBUTTON CAPTION 'Flip Image' ;
    SIZE 80,20 ACTION {||FlipImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 10 DCPUSHBUTTON CAPTION 'Rotate Image' ;
    SIZE 80,20 ACTION {||RotateImage(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 10 DCPUSHBUTTON CAPTION 'Load Array' ;
    SIZE 80,20 ACTION {||LoadArray(hDC1,aPixel)}

*-------- LC

@ DCGUI_ROW, DCGUI_COL + 10 DCPUSHBUTTON CAPTION 'Spectrum Spiral' ;                  // Моя первая пиксельная функция
    SIZE 100,20 ACTION {||SpectrumSpiral(hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 10 DCPUSHBUTTON CAPTION 'OutLine Image' ;                    // Контур изображения
    SIZE 110,20 ACTION {||OutLine(hDC1,hDC2,aPixel)}

@ DCGUI_ROW, DCGUI_COL + 10 DCPUSHBUTTON CAPTION 'Trimming Image' ;                   // Контур изображения
    SIZE 110,20 ACTION {||Trimming(hDC1,hDC2,aPixel)}

DCGETOPTIONS PIXEL

DCREAD GUI FIT TITLE 'Pixel Test' OPTIONS GetOptions ;
   EVAL {||ClearImage(hDC2,aPixel)}

RETURN nil

* ---------

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 ClearImage( hDC2, aPixel )

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
LOCAL nColor := AutomationTranslateColor(GraMakeRGBColor({255,255,255}),.f.)

FOR i := 0 TO nXSize
  FOR j := 0 TO nYSize
    SetPixel(hDC2,i,j,nColor)
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION TransferImage( hDC1, hDC2, aPixel )

LOCAL i, j, nColor, lEmptyArray := aPixel[1,1] == nil, ;
      nXSize := Len(aPixel), nYSize := Len(aPixel[1])

FOR i := 0 TO nXSize-1
  FOR j := 0 TO nYSize-1
    IF lEmptyArray
      SetPixel(hDC2,i,j,GetPixel(hDC1,i,j))
    ELSE
      SetPixel(hDC2,i,j,aPixel[i+1,j+1])
    ENDIF
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION FlipImage( hDC1, hDC2, 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
    IF lEmptyArray
      SetPixel(hDC2,j,i,GetPixel(hDC1,j,nXSize-i))
    ELSE
      SetPixel(hDC2,j,i,aPixel[i+1,j+1])
    ENDIF
  NEXT
NEXT

RETURN nil

* ----------

FUNCTION RotateImage( hDC1, hDC2, 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
    IF lEmptyArray
      SetPixel(hDC2,i,j,GetPixel(hDC1,j,nXSize-i))
    ELSE
      SetPixel(hDC2,i,j,aPixel[j+1,nXSize-i])
    ENDIF
  NEXT
NEXT

RETURN nil

* ---------

PROC appsys ; RETURN

* ---------

STATIC FUNCTION ShowColor( hDC, aCoords, oSay, oStatic )

LOCAL nColor

aCoords[2] := oStatic:currentSize()[2] - aCoords[2]

nColor := GetPixel(hDC,aCoords[1],aCoords[2])

oSay:setCaption('Color: ' + DC_Array2String(GraGetRGBIntensity(AutomationTranslateColor(nColor,.T.))) + ;
   ' Coords: ' + DC_Array2String(aCoords))

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

* --------

FUNCTION OutLine(hDC1, hDC2, aPixel )

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])


          *** Нарисовать контур изображения символа

          fColor := AutomationTranslateColor(GraMakeRGBColor({255,0,0}),.f.) 

          FOR x = 1 TO nXSize
              mPixOld = GetPixel(hDC1, x-1, 0)
              FOR y = 1 TO nYSize
                  mPixNew = GetPixel(hDC1, x-1, y-1)
                  IF mPixOld <> mPixNew
                     mPixOld =  mPixNew
                     SetPixel(hDC2, x-1, y-1, fColor)
                  ENDIF
              NEXT
          NEXT
          FOR y = 1 TO nYSize
              mPixOld = GetPixel(hDC1, 0, y-1)
              FOR x = 1 TO nXSize
                  mPixNew = GetPixel(hDC1, x-1, y-1)
                  IF mPixOld <> mPixNew
                     mPixOld =  mPixNew
                     SetPixel(hDC2, x-1, y-1, fColor)
                  ENDIF
              NEXT
          NEXT

*  cFileName = ConvToAnsiCP("Спектр в форме спирали.bmp")
*  DC_Scrn2ImageFile( oStatic, cFileName )

RETURN nil

* --------

FUNCTION SpectrumSpiral( hDC2, aPixel )

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])

   PUBLIC X_MaxW := nXSize, Y_MaxW := nYSize                // Размер графического окна для изображения в пикселях (чтобы помещалось на ультрабук)

   *** Расчет позиций центров изображений в стилях "Контур" и "Витраж"

   mRadiusMax = X_MaxW / 4

   Ax = X_MaxW / ( 2 * mRadiusMax )
   Ay = Y_MaxW / ( 2 * mRadiusMax )

   X0L = X_MaxW / 2                 // Для левого изображения
   Y0L = Y_MaxW / 2

   X0R = X_MaxW / 2                 // Для правого изображения
   Y0R = Y_MaxW / 2 


   ****** Гармонические последовательности цветов

   Column = 0

   Ax     = 0.05
   Ay     = 0.05

   Kx     = 1
   Ky     = 1

   FOR n = 0 TO 360*30 STEP 0.1

       ma := 127
       mb := 127
       mc := 127

       mU := 0
       mV := 120
       mW := 240

       mColor = n

       R := INT( ma * (1 + COS( ( mColor + mU ) * 3.14159265358979323846 / 180 ) ) )
       G := INT( mb * (1 + COS( ( mColor + mV ) * 3.14159265358979323846 / 180 ) ) )
       B := INT( mc * (1 + COS( ( mColor + mW ) * 3.14159265358979323846 / 180 ) ) )

       fColor := GraMakeRGBColor({ R, G, B })

       ***** Закрасить фон прямоугольника ***************

*      GraSetColor( hDC2, fColor, fColor )

       fColor := AutomationTranslateColor(GraMakeRGBColor({R,G,B}),.f.) 

       Column = Column + 1

       X1 := X0R + Ax * Column * COS((Column-1) * 3.14159265358979323846 / 180 ) * Kx
       Y1 := Y0R + Ay * Column * SIN((Column-1) * 3.14159265358979323846 / 180 ) * Ky

*      GraArc( oPS, { X1, Y1 }, RS, ,,, GRA_OUTLINEFILL )
       
       IF X0R - X_MaxW / 2 <= X1 .AND. X1 <= X0R + X_MaxW / 2
       IF Y0R - Y_MaxW / 2 <= Y1 .AND. Y1 <= Y0R + Y_MaxW / 2
          SetPixel(hDC2, X1, Y1, fColor)
       ENDIF
       ENDIF

   NEXT

*  cFileName = ConvToAnsiCP("Спектр в форме спирали.bmp")
*  DC_Scrn2ImageFile( oStatic, cFileName )

RETURN nil

* ----------

FUNCTION Trimming(hDC1, hDC2, aPixel)

LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])

   fColor := AutomationTranslateColor(GraMakeRGBColor({255,0,0}),.f.) 

   *** Определить координаты левой границы области отображения X1

   X1 = +9999999
   FOR x = 1 TO nXSize
       mPixOld = GetPixel(hDC1, x-1, 0)
       FOR y = 1 TO nYSize
           mPixNew = GetPixel(hDC1, x-1, y-1)
*          MsgBox("x="+STR(x)+", y="+STR(y)+",  mPix="+STR(mPix))
           IF mPixNew <> mPixOld
              X1 = MIN(X1,x)
*             GraMarker  ( oPS, { x-1, y-1 } )
              SetPixel(hDC2, x-1, y-1, fColor)
              EXIT
           ENDIF
       NEXT
   NEXT

   *** Определить координаты правой границы области отображения X2

   X2 = -9999999
   FOR x = nXSize TO 1 STEP -1
       mPixOld = GetPixel(hDC1, x-1, 0)
       FOR y = 1 TO nYSize
           mPixNew = GetPixel(hDC1, x-1, y-1)
           IF mPixNew <> mPixOld
              X2 = MAX(X2,x)
*             GraMarker  ( oPS, { x-1, y-1 } )
              SetPixel(hDC2, x-1, y-1, fColor)
              EXIT
           ENDIF
       NEXT
   NEXT

   *** Определить координаты верхней границы области отображения Y2

   Y1 = +9999999
   FOR y = 1 TO nYSize
       mPixOld = GetPixel(hDC1, 0, y-1)
       FOR x = 1 TO nXSize
           mPixNew = GetPixel(hDC1, x-1, y-1)
           IF mPixNew <> mPixOld
              Y1 = MIN(Y1,y)
*             GraMarker  ( oPS, { x-1, y-1 } )
              SetPixel(hDC2, x-1, y-1, fColor)
              EXIT
           ENDIF
       NEXT
   NEXT

   *** Определить координаты нижней границы области отображения Y1

   Y2 = -9999999
   FOR y = nYSize TO 1 STEP -1
       mPixOld = GetPixel(hDC1, 0, y-1)
       FOR x = 1 TO nXSize
           mPixNew = GetPixel(hDC1, x-1, y-1)
           IF mPixNew <> mPixOld
              Y2 = MAX(Y2,y)
*             GraMarker  ( oPS, { x-1, y-1 } )
              SetPixel(hDC2, x-1, y-1, fColor)
              EXIT
           ENDIF
       NEXT
   NEXT

   *** Нарисовать прямоугольник области отображения символов с синими границами

   IF X1 > 0 .AND. Y2 > 0 .AND. X2 > 0 .AND. Y2 > 0

*     GraSetColor( oPS, GRA_CLR_RED, GRA_CLR_RED )
*     GraBox( oPS, { X1, Y1 }, { X2, Y2 }, GRA_OUTLINE ) 
*     GraSetColor( oPS, GRA_CLR_BLACK, GRA_CLR_BLACK )

*     cFileName = "All_images.bmp"
*     ERASE( cFileName );DC_Scrn2ImageFile( oStatic, cFileName )            // Стереть старый файл и записать новый

*     MsgBox("{X1="+ALLTRIM(STR(X1))+", Y1="+ALLTRIM(STR(Y1))+"}, {X2="+ALLTRIM(STR(X2))+", Y2="+ALLTRIM(STR(Y2))+"}")

      fColor := AutomationTranslateColor(GraMakeRGBColor({0,0,255}),.f.) 

      FOR x=X1 TO X2
          SetPixel(hDC2, x-1, Y1-1, fColor)
      NEXT
      FOR x=X1 TO X2
          SetPixel(hDC2, x-1, Y2+1, fColor)
      NEXT
      FOR y=Y1 TO Y2
          SetPixel(hDC2, X1-2, y-1, fColor)
      NEXT
      FOR y=Y1 TO Y2
          SetPixel(hDC2, X2+1, y-1, fColor)
      NEXT

  ENDIF


RETURN nil

* ----------
[/size]
I also want to be able to use other features as described in this example. When I start using these functions to the buttons as in Example Roger, then no problem. But I would like to have processed all the graphic image files are symbols formed earlier. At the same time that the user did not have the image after each click on the button. When arrays of pixel values ​​appropriate to various images are formed, I want to use my developed artificial intelligence techniques based on information theory, to solve various problems. This is a continuation of development and research, described in the articles:
http://ej.kubagro.ru/2015/06/pdf/09.pdf (Alaska)
http://ej.kubagro.ru/2009/07/pdf/05.pdf (CLIPPER)
http://ej.kubagro.ru/2009/02/pdf/10.pdf (CLIPPER)
It will also be used for educational purposes. Of course I'm not going to explore only the characters of different fonts. Generator character images I made for training purposes and to debug mode for processing real images and to solve various problems with real images.
Last edited by Eugene Lutsenko on Mon Jul 20, 2015 10:29 pm, edited 3 times in total.

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

#17 Post by rdonnay »

I am still lost and trying to understand what you want from me.
Please don't post any more source code.

Just explain what you want me to do to your existing application.
What is it that is working and what is it that is NOT working?

Is the URL a link to a working application that you want to have modified?

Is there anyone else on this forum who understands what Eugene is asking me to do for him?
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

#18 Post by Eugene Lutsenko »

I'm an example of the function GetPixel() in LoadArray() on an array of image files without any user to move from one image to another. I also ask you to forgive me for inarticulate English if it is generally permissible to call English. Article I cited as an example of work in that direction, which I am now developing its own system of Aidos.

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

#19 Post by Eugene Lutsenko »

Auge_Ohr wrote:hi,

i still do not understand what you want to do with GetPixel() and those Font ?
why you generate those (big) Font ... what do you want to do with it ?
when using a "big" Truetype Font you can use "every Size" ... but if you use Size bigger than "real" ( e.g. 72 Point ) it will be resize by Windows OS().
also Cleartype is default enable, which GraStringAt() use ( PDR 6314 ), so Pixel on Edge are "not real".

tell us the hole Story what you want todo ... else Answer may point into wrong Direction.


while GraQueryTextBox() is "slow" try this Sample from Günter Beyes.
it also show you how to use Windows API CreateFont()
GraQuery.zip
Jimmy!
Alaska 32-Bit Linker Version 1.90.355
Copyright (c) Alaska Software 1997-2009. All rights reserved.

ALINK: fatal error ALK4001: cannot open file "gdi32.lib"

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

#20 Post by rdonnay »

I'm an example of the function GetPixel() in LoadArray() on an array of image files without any user to move from one image to another.
Do I understand that you have an array of image colors (RGB) and that you want to display an image on the screen from that array?

Are you saying that you have many arrays (multi-dimensional) and that you want to step thru all the arrays and display the images?

Do I have this in reverse?

Are you saying that you have an array of images that contains file names and that you want to display the images and then save them to arrays?

Maybe you should post your answer in Russian language and I will try to translate with software.
The eXpress train is coming - and it has more cars.

Post Reply