Page 1 of 5

Generating and saving images of characters

Posted: Tue Jul 07, 2015 1:50 am
by Eugene Lutsenko
To conduct laboratory studies and debugging work with images I have developed (of course, based on the development of Roger) a program generation and conservation of character images:
http://lc.kubagro.ru/Dima/Gen_fonts.rar

But to go to the next image has to press a key that is not always convenient. Is it possible to somehow make that image appear on the screen one by one from the first to the last non-stop?

Can I use functions DC_Scrn2ImageFile () or otherwise somehow saved as an image file, not all window and part of it, given the coordinates?

Code: Select all

STATIC snHdll

PROC appsys ; RETURN

*************************
FUNCTION Main()

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

DC_IconDefault(1000)

PUBLIC aPar[6]
IF .NOT. FILE('_ParGenSimb.arx')
   AFILL(aPar, .T.)
   aPar[1] = .T.
ELSE
   aPar = DC_ARestore("_ParGenSimb.arx")
ENDIF

PUBLIC cFont := Pad('400.Arial Bold',50)
IF .NOT. FILE('_Font.txt')
   cFont := Pad('400.Arial Bold',50)
ELSE
   cFont = FileStr('_Font.txt')
ENDIF
cFont = cFont + SPACE(50-LEN(ALLTRIM(cFont))+1)

@ 0,0 DCGROUP oGroup1 CAPTION '1. Задание параметров и генерация изображений символов, просмотр таблицы шрифта' SIZE 90.0, 2.5
@ 1,2 DCSAY 'Задайте тип и размер шрифта:' GET cFont POPUP {|c|DC_PopFont(c)} SAYSIZE 0 SAYBOTTOM PARENT oGroup1

@ 3, 0 DCGROUP oGroup2 CAPTION 'Задайте, какие символы отображать:' SIZE 90.0, 7.5

@ 1, 2 DCCHECKBOX aPar[1] PROMPT 'Цифры'       PARENT oGroup2
@ 2, 2 DCCHECKBOX aPar[2] PROMPT 'Буквы'       PARENT oGroup2
@ 3, 2 DCCHECKBOX aPar[3] PROMPT 'Латинские'   PARENT oGroup2
@ 4, 2 DCCHECKBOX aPar[4] PROMPT 'Русские'     PARENT oGroup2
@ 5, 2 DCCHECKBOX aPar[5] PROMPT 'Заглавные'   PARENT oGroup2
@ 6, 2 DCCHECKBOX aPar[6] PROMPT 'Строчные'    PARENT oGroup2

@ 2,55 DCPUSHBUTTON CAPTION 'Отобразить шрифт' SIZE 20, 3.8 ACTION {||DisplayFonts(cFont)} PARENT oGroup2

DCREAD GUI;
      TO lExit ;
      FIT;
      ADDBUTTONS;
      MODAL;
      TITLE "1. Задание параметров и генерация изображений символов, просмотр таблицы шрифта"

********************************************************************
      IF lExit
         ** Button Ok
      ELSE
         RETURN nil
      ENDIF
********************************************************************

DC_ASave(aPar, "_ParGenSimb.arx")

ERASE('_Font.txt')
StrFile(ALLTRIM(cFont), '_Font.txt')              // Запись текстового файла _Font.txt

FOR mSimb = 1 TO 255

    ERASE('_Simb.txt')
    StrFile(ALLTRIM(STR(mSimb)), '_Simb.txt')     // Запись текстового файла _Simb.txt
*   StrFile(ALLTRIM(STR(mSimb)), ConvToAnsiCP("Привет.ini"))

    IF aPar[1]           // Цифры
       IF 48 <= mSimb .AND. mSimb <= 57
          DrawSimbol(cFont)
       ENDIF
    ENDIF
    IF aPar[2]           // Буквы
       IF aPar[3]        // Латинские
          IF aPar[5]     // Заглавные
             IF 65 <= mSimb .AND. mSimb <= 90
                DrawSimbol(cFont)
             ENDIF
          ENDIF
          IF aPar[6]     // Строчные
             IF 97 <= mSimb .AND. mSimb <= 122
                DrawSimbol(cFont)
             ENDIF
          ENDIF
       ENDIF
       IF aPar[4]        // Русские
          IF aPar[5]     // Заглавные
             IF 128 <= mSimb .AND. mSimb <= 159
                DrawSimbol(cFont)
             ENDIF
          ENDIF
          IF aPar[6]     // Строчные
             IF 160 <= mSimb .AND. mSimb <= 175
                DrawSimbol(cFont)
             ENDIF
             IF 224 <= mSimb .AND. mSimb <= 239
                DrawSimbol(cFont)
             ENDIF
          ENDIF
       ENDIF
    ENDIF
NEXT

RETURN nil

* -------------

FUNCTION DisplayFonts( cFont )

LOCAL GetList[0], i, nRow, nCol

cFont   =     FileStr('_Font.txt')

cFont := Alltrim(cFont)
nRow := 1
nCol := 0

FOR i := 1 TO 255
  @ nRow, nCol DCSAY Str(i,3) FONT '10.Lucida Console' SAYRIGHTBOTTOM SAYSIZE 10
  @ DCGUI_ROW, DCGUI_COL + 10 DCSAY Chr(i) FONT cFont SAYSIZE 0 SAYBOTTOM
  nRow++
  IF nRow % 33 == 0
    nRow := 1
    nCol += 18
  ENDIF
NEXT

DCREAD GUI FIT TITLE 'Displaying Fonts: ' + cFont MODAL

RETURN nil


**********************************************
******** ВИЗУАЛИЗАЦИЯ СИМВОЛА ****************
**********************************************
FUNCTION DrawSimbol( cFont)

   LOCAL GetList := {}, oStatic

   PRIVATE nEvent, mp1, mp2, oXbp                      // Переменные анализа событий

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                // Размер графического окна для самого графика в пикселях

   cFont   =     FileStr('_Font.txt')

   @ 2,1 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX SIZE X_MaxW+11, Y_MaxW+20 PIXEL; // Размер окна в пикселях (от Тома)
         OBJECT oStatic;
         EVAL {|| _PresSpaceSimbol( oStatic, cFont) }


   DCREAD GUI ;
      TITLE "Рисование изображений символов в системе ЭЙДОС-X++";   // Надпись на окне графика
      FIT ;
      BUTTONS DCGUI_BUTTON_EXIT

RETURN NIL

*************************************************
STATIC FUNCTION _PresSpaceSimbol( oStatic, cFont )

   LOCAL oPS, oDevice

   cFont   =     FileStr('_Font.txt')

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                // Размер графического окна для самого графика в пикселях

   oPS := XbpPresSpace():new()         // Create a PS
   oDevice := oStatic:winDevice()      // Get the device context
   oPS:create( oDevice )               // Link device context to PS
   oPS:SetViewPort( { 0, 0, X_MaxW, Y_MaxW } )
   oStatic:paint := {|mp1,mp2,obj| mp1 := LC_DrawSimbol( oPS, oStatic, cFont ) }

RETURN NIL

*******************************************************
STATIC FUNCTION LC_DrawSimbol( oPS, oStatic, cFont )

   LOCAL oBitmap 

   cFont   =     FileStr('_Font.txt')
   mSimbol = VAL(FileStr('_Simb.txt'))

*  MsgBox(STR(mSimbol)+' '+CHR(mSimbol))

   IF LEN(CHR(mSimbol)) = 0
      RETURN NIL
   ENDIF

   PRIVATE X0 := 0 + X_MaxW/2
   PRIVATE Y0 := 5 + Y_MaxW/2                          // Начало координат по осям X и Y

   PRIVATE W_Wind := X_MaxW - X0                       // Ширина окна для самого графика
   PRIVATE H_Wind := Y_MaxW - Y0                       // Высота окна для самого графика

   **** Написать заголовок диаграммы

   aFonts := XbpFont():new():list()                    // Все доступные шрифты

   oFont := XbpFont():new():create(cFont)
   GraSetFont(oPS , oFont)                             // установить шрифт
   aAttrF := ARRAY( GRA_AS_COUNT ) 
   aAttrF [ GRA_AS_COLOR      ] := GRA_CLR_BLACK 
   aAttrF [ GRA_AS_HORIZALIGN ] := GRA_HALIGN_CENTER   // Выравнивание символов по горизонтали по центру относительно точки начала вывода
   aAttrF [ GRA_AS_VERTALIGN  ] := GRA_VALIGN_HALF     // Выравнивание символов по вертикали по средней линии относительно точки начала вывода
   GraSetAttrString( oPS, aAttrF )                     // Установить символьные атрибуты

   mTitle = CHR(mSimbol)
   aTxtPar = DC_GraQueryTextbox(mTitle, oFont)         // {101,16} Определяет длину и высоту текста в пикселях для некоторых шрифтов
*  MsgBox("Длина текста в пикселях="+ALLTRIM(STR(aTxtPar[1]))+". Высота текста в пикселях="+ALLTRIM(STR(aTxtPar[2])))
   GraStringAt( oPS, { X_MaxW/2, Y_MaxW/2+aTxtPar[2]+5 }, mTitle)

   ***** Запись изображения символа в папку с именем - названием шрифта: cFont в виде файла с имененем: Символ: CHR(mSimbol)

*  DIRCHANGE(M_ApplsPath+"/Inp_data/")

   mFontDir = ALLTRIM(cFont)
   mFontDir = STRTRAN(mFontDir,' ','_')
   mFontDir = STRTRAN(mFontDir,'.','_')

   IF FILEDATE(mFontDir,16) = CTOD("//")
      DIRMAKE(mFontDir)
      Mess = 'В папке текущего приложения не было директории: "'+mFontDir+'" для изображений символов этого шрифта и она была создана!'
      LB_Warning(Mess, 'Рисование изображений символов в системе "ЭЙДОС-X++"' )
   ENDIF

   DIRCHANGE(mFontDir)      // Перейти в папку mFontDir

*  cFileName = 'CHR'+STRTRAN(STR(mSimbol,3)," ","0")+".bmp"    // Если цифры или латинские буквы - имя = сам символ, а иначе код: CHR###
*  cFileName = ConvToAnsiCP(CHR(mSimbol))+".bmp"               // Чтобы в именах файлов можно было использовать русские символы

   **** Формирование имени графического файла

   IF aPar[1]           // Цифры
      IF 48 <= mSimb .AND. mSimb <= 57
         cFileName = "Num "+ConvToAnsiCP(CHR(mSimbol))+".bmp"                           // Чтобы в именах файлов можно было использовать русские символы
      ENDIF
   ENDIF
   IF aPar[2]           // Буквы
      IF aPar[3]        // Латинские
         IF aPar[5]     // Заглавные
            IF 65 <= mSimb .AND. mSimb <= 90
               cFileName = "Eng Upper "+ConvToAnsiCP(CHR(mSimbol))+".bmp"               // Чтобы в именах файлов можно было использовать русские символы
            ENDIF
         ENDIF
         IF aPar[6]     // Строчные
            IF 97 <= mSimb .AND. mSimb <= 122
               cFileName = "Eng Lower "+ConvToAnsiCP(CHR(mSimbol))+".bmp"               // Чтобы в именах файлов можно было использовать русские символы
            ENDIF
         ENDIF
      ENDIF
      IF aPar[4]        // Русские
         IF aPar[5]     // Заглавные
            IF 128 <= mSimb .AND. mSimb <= 159
               cFileName = "Rus Upper "+ConvToAnsiCP(CHR(mSimbol))+".bmp"               // Чтобы в именах файлов можно было использовать русские символы
            ENDIF
         ENDIF
         IF aPar[6]     // Строчные
            IF 160 <= mSimb .AND. mSimb <= 175
               cFileName = "Rus Lower "+ConvToAnsiCP(CHR(mSimbol))+".bmp"               // Чтобы в именах файлов можно было использовать русские символы
            ENDIF
            IF 224 <= mSimb .AND. mSimb <= 239
               cFileName = "Rus Lower "+ConvToAnsiCP(CHR(mSimbol))+".bmp"               // Чтобы в именах файлов можно было использовать русские символы
            ENDIF
         ENDIF
      ENDIF
   ENDIF

   DC_Scrn2ImageFile( oStatic, cFileName )

*  DIRCHANGE(Disk_dir)
   DIRCHANGE('..')

   ***** Джимми ************

*  LOCAL oBitmap // В начале
*  oBitmap := GraSaveScreen( oPS, oStatic:CurrentPos() , oStatic:CurrentSize() )
*  DIRCHANGE(mFontDir)      // Перейти в папку mFontDir
*  cFileName = 'CHR'+STRTRAN(STR(mSimbol,3)," ","0")+".bmp"    // Если цифры или латинские буквы  - имя - прямо сам символ, а иначе код: CHR###
*  oBitmap:Savefile(cFileName)
*  DIRCHANGE("..")          // Перейти в текущую папку

RETURN NIL


******** Display a warning message
******** Может выдавать сообщения элементами массива и без ctitle:

*message := {}
*AADD(message,'1-е сообщение')
*AADD(message,'2-е сообщение')
*AADD(message,'3-е сообщение')
*LB_Warning( message )

FUNCTION LB_Warning( message, ctitle )

  LOCAL aMsg := {}
  DEFAULT cTitle TO ''
  IF valtype(message) # 'A'
    aadd(aMsg,message)
  ELSE
    aMsg := message
  ENDIF
  IF LEN(ALLTRIM(cTitle)) > 0
     DC_MsgBox( ,,aMsg,cTitle)
  ELSE
     DC_MsgBox( ,,aMsg,'(C) Универсальная когнитивная аналитическая система "Эйдос-Х++"')
  ENDIF

RETURN NIL
*******************************************************
[/size]

Re: Generating and saving images of characters

Posted: Tue Jul 07, 2015 7:07 am
by rdonnay
I made a few changes to your code.

1. You don't need all those #include files and libraries.

All you need are these:

Code: Select all

#INCLUDE "dcdialog.CH"
#INCLUDE "common.CH"
#INCLUDE "appevent.CH"

#pragma library( "dclipx.lib" )
#pragma library( "xbtbase1.lib" )
#pragma library( "xbtbase2.lib" )
2. Change the functioin DrawSimbol to the following:

Code: Select all

FUNCTION DrawSimbol( cFont)

   LOCAL GetList := {}, oStatic

   PRIVATE nEvent, mp1, mp2, oXbp                      // ¥à¥¬¥­­ë¥  ­ «¨§  ᮡë⨩

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                //  §¬¥à £à ä¨ç¥áª®£® ®ª­  ¤«ï á ¬®£® £à ä¨ª  ¢ ¯¨ªá¥«ïå

   cFont   =     FileStr('_Font.txt')

   @ 2,1 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX SIZE X_MaxW+11, Y_MaxW+20 PIXEL; //  §¬¥à ®ª­  ¢ ¯¨ªá¥«ïå (®â ’®¬ )
         OBJECT oStatic;

   DCREAD GUI ;
      TITLE "¨á®¢ ­¨¥ ¨§®¡à ¦¥­¨© ᨬ¢®«®¢ ¢ á¨á⥬¥ ‰„Ž‘-X++";   //  ¤¯¨áì ­  ®ª­¥ £à ä¨ª 
      FIT ;
      EVAL {|o| _PresSpaceSimbol( oStatic, cFont), ;
              PostAppEvent(xbeP_Close,,,o) }

RETURN NIL
3. Change the function _PresSpaceSimbol to the following:

Code: Select all

STATIC FUNCTION _PresSpaceSimbol( oStatic, cFont )

   LOCAL oPS, oDevice

   cFont   =     FileStr('_Font.txt')

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                //  §¬¥à £à ä¨ç¥áª®£® ®ª­  ¤«ï á ¬®£® £à ä¨ª  ¢ ¯¨ªá¥«ïå

   oPS := XbpPresSpace():new()         // Create a PS
   oDevice := oStatic:winDevice()      // Get the device context
   oPS:create( oDevice )               // Link device context to PS
   oPS:SetViewPort( { 0, 0, X_MaxW, Y_MaxW } )
   // oStatic:paint := {|mp1,mp2,obj| mp1 := LC_DrawSimbol( oPS, oStatic, cFont ) }
   LC_DrawSimbol( oPS, oStatic, cFont )

RETURN NIL

Re: Generating and saving images of characters

Posted: Tue Jul 07, 2015 11:28 am
by Eugene Lutsenko
Thank you, Roger! Everything went really well. A library and ch-Files - I have it not for this program, and for the whole system. How to save as an image file, not all window and the rectangle defined by the coordinates (the height and width of the character I am able to learn).

Re: Generating and saving images of characters

Posted: Tue Jul 07, 2015 11:37 am
by Auge_Ohr
Eugene Lutsenko wrote:How to save as an image file, not all window and the rectangle defined by the coordinates (the height and width of the character I am able to learn).
use GraBitBlt()
aSourceRect := { <nX1>, <nY1> [,<nX2>, <nY2>] } is the Source retangle

Re: Generating and saving images of characters

Posted: Tue Jul 07, 2015 9:26 pm
by Eugene Lutsenko
I did the generation of images of characters in a single window.
With GraBitBit () will understand. It seems that this is what you need. THANK!

Code: Select all

PROC appsys ; RETURN

*************************
FUNCTION Main()

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

DC_IconDefault(1000)

PUBLIC aPar[6]
IF .NOT. FILE('_ParGenSimb.arx')
   AFILL(aPar, .T.)
   aPar[1] = .T.
ELSE
   aPar = DC_ARestore("_ParGenSimb.arx")
ENDIF

PUBLIC cFont := Pad('400.Arial Bold',50)
IF .NOT. FILE('_Font.txt')
   cFont := Pad('400.Arial Bold',50)
ELSE
   cFont = FileStr('_Font.txt')
ENDIF
cFont = cFont + SPACE(50-LEN(ALLTRIM(cFont))+1)

@ 0,0 DCGROUP oGroup1 CAPTION '1. Задание параметров и генерация изображений символов, просмотр таблицы шрифта' SIZE 90.0, 2.5
@ 1,2 DCSAY 'Задайте тип и размер шрифта:' GET cFont POPUP {|c|DC_PopFont(c)} SAYSIZE 0 SAYBOTTOM PARENT oGroup1

@ 3, 0 DCGROUP oGroup2 CAPTION 'Задайте, какие символы отображать:' SIZE 90.0, 7.5

@ 1, 2 DCCHECKBOX aPar[1] PROMPT 'Цифры'       PARENT oGroup2
@ 2, 2 DCCHECKBOX aPar[2] PROMPT 'Буквы'       PARENT oGroup2
@ 3, 2 DCCHECKBOX aPar[3] PROMPT 'Латинские'   PARENT oGroup2
@ 4, 2 DCCHECKBOX aPar[4] PROMPT 'Русские'     PARENT oGroup2
@ 5, 2 DCCHECKBOX aPar[5] PROMPT 'Заглавные'   PARENT oGroup2
@ 6, 2 DCCHECKBOX aPar[6] PROMPT 'Строчные'    PARENT oGroup2

@ 2,55 DCPUSHBUTTON CAPTION 'Отобразить шрифт' SIZE 20, 3.8 ACTION {||DisplayFonts(cFont)} PARENT oGroup2

DCREAD GUI;
      TO lExit ;
      FIT;
      ADDBUTTONS;
      MODAL;
      TITLE "1. Задание параметров и генерация изображений символов, просмотр таблицы шрифта"

********************************************************************
      IF lExit
         ** Button Ok
      ELSE
         RETURN nil
      ENDIF
********************************************************************

DC_ASave(aPar, "_ParGenSimb.arx")

ERASE('_Font.txt')
StrFile(ALLTRIM(cFont), '_Font.txt')              // Запись текстового файла _Font.txt

DrawSimbol( cFont )

RETURN nil

* -------------

FUNCTION DisplayFonts( cFont )

LOCAL GetList[0], i, nRow, nCol

cFont   =     FileStr('_Font.txt')

cFont := Alltrim(cFont)
nRow := 1
nCol := 0

FOR i := 1 TO 255
  @ nRow, nCol DCSAY Str(i,3) FONT '10.Lucida Console' SAYRIGHTBOTTOM SAYSIZE 10
  @ DCGUI_ROW, DCGUI_COL + 10 DCSAY Chr(i) FONT cFont SAYSIZE 0 SAYBOTTOM
  nRow++
  IF nRow % 33 == 0
    nRow := 1
    nCol += 18
  ENDIF
NEXT

DCREAD GUI FIT TITLE 'Displaying Fonts: ' + cFont MODAL

RETURN nil


**********************************************
******** ВИЗУАЛИЗАЦИЯ СИМВОЛА ****************
**********************************************
FUNCTION DrawSimbol( cFont )

   LOCAL GetList := {}, oStatic

   PRIVATE nEvent, mp1, mp2, oXbp                      // Переменные анализа событий

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                // Размер графического окна для самого графика в пикселях

   cFont   =     FileStr('_Font.txt')

*  @ 2,1 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX SIZE X_MaxW+11, Y_MaxW+20 PIXEL; // Размер окна в пикселях (от Тома)
   @ 2,1 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX SIZE X_MaxW, Y_MaxW PIXEL;       // Размер окна в пикселях (от Тома)
         OBJECT oStatic;
         EVAL {|| _PresSpaceSimbol( oStatic, cFont) }


   DCREAD GUI ;
      TITLE "Рисование изображений символов в системе ЭЙДОС-X++";   // Надпись на окне графика
      FIT ;
      BUTTONS DCGUI_BUTTON_EXIT

RETURN NIL

*************************************************
STATIC FUNCTION _PresSpaceSimbol( oStatic, cFont )

   LOCAL oPS, oDevice

   cFont   =     FileStr('_Font.txt')

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                // Размер графического окна для самого графика в пикселях

   oPS := XbpPresSpace():new()         // Create a PS
   oDevice := oStatic:winDevice()      // Get the device context
   oPS:create( oDevice )               // Link device context to PS
   oPS:SetViewPort( { 0, 0, X_MaxW, Y_MaxW } )
   oStatic:paint := {|mp1,mp2,obj| mp1 := LC_DrawSimbol( oPS, oStatic, cFont ) }

RETURN NIL

*******************************************************
STATIC FUNCTION LC_DrawSimbol( oPS, oStatic, cFont )

   LOCAL oBitmap 

   cFont   =     FileStr('_Font.txt')
   aPar = DC_ARestore("_ParGenSimb.arx")

   PRIVATE X0 := 0 + X_MaxW/2
   PRIVATE Y0 := 5 + Y_MaxW/2                          // Начало координат по осям X и Y

   PRIVATE W_Wind := X_MaxW - X0                       // Ширина окна для самого графика
   PRIVATE H_Wind := Y_MaxW - Y0                       // Высота окна для самого графика

   **** Написать заголовок диаграммы

   aFonts := XbpFont():new():list()                    // Все доступные шрифты

   oFont := XbpFont():new():create(cFont)
   GraSetFont(oPS , oFont)                             // установить шрифт
   aAttrF := ARRAY( GRA_AS_COUNT ) 
   aAttrF [ GRA_AS_COLOR      ] := GRA_CLR_BLACK 
   aAttrF [ GRA_AS_HORIZALIGN ] := GRA_HALIGN_LEFT     // Выравнивание символов по горизонтали по левому краю
   aAttrF [ GRA_AS_VERTALIGN  ] := GRA_VALIGN_BOTTOM   // Выравнивание символов по вертикали   по низу
   GraSetAttrString( oPS, aAttrF )                     // Установить символьные атрибуты

   ***** Запись изображения символа в папку с именем - названием шрифта: cFont в виде файла с имененем: Символ: CHR(mSimb)

*  DIRCHANGE(M_ApplsPath+"/Inp_data/")

   mFontDir = ALLTRIM(cFont)
   mFontDir = STRTRAN(mFontDir,' ','_')
   mFontDir = STRTRAN(mFontDir,'.','_')

   IF FILEDATE(mFontDir,16) = CTOD("//")
      DIRMAKE(mFontDir)
      Mess = 'В папке текущего приложения не было директории: "'+mFontDir+'" для изображений символов этого шрифта и она была создана!'
      LB_Warning(Mess, 'Рисование изображений символов в системе "ЭЙДОС-X++"' )
   ENDIF

   DIRCHANGE(mFontDir)      // Перейти в папку mFontDir

   *** Формирование графического файла

   FOR mSimb = 1 TO 255

       cFileName = "No name"                                                    // Чтобы не записывать изображений, которые не нужно

       IF aPar[1]           // Цифры
          IF 48 <= mSimb .AND. mSimb <= 57
             cFileName = "Num "+ConvToAnsiCP(CHR(mSimb))+".bmp"                 // Чтобы в именах файлов можно было использовать русские символы
          ENDIF
       ENDIF
       IF aPar[2]           // Буквы
          IF aPar[3]        // Латинские
             IF aPar[5]     // Заглавные
                IF 65 <= mSimb .AND. mSimb <= 90
                   cFileName = "Eng Upper "+ConvToAnsiCP(CHR(mSimb))+".bmp"     // Чтобы в именах файлов можно было использовать русские символы
                ENDIF
             ENDIF
             IF aPar[6]     // Строчные
                IF 97 <= mSimb .AND. mSimb <= 122
                   cFileName = "Eng Lower "+ConvToAnsiCP(CHR(mSimb))+".bmp"     // Чтобы в именах файлов можно было использовать русские символы
                ENDIF
             ENDIF
          ENDIF
          IF aPar[4]        // Русские
             IF aPar[5]     // Заглавные
                IF 128 <= mSimb .AND. mSimb <= 159
                   cFileName = "Rus Upper "+ConvToAnsiCP(CHR(mSimb))+".bmp"     // Чтобы в именах файлов можно было использовать русские символы
                ENDIF
             ENDIF
             IF aPar[6]     // Строчные
                IF 160 <= mSimb .AND. mSimb <= 175
                   cFileName = "Rus Lower "+ConvToAnsiCP(CHR(mSimb))+".bmp"     // Чтобы в именах файлов можно было использовать русские символы
                ENDIF
                IF 224 <= mSimb .AND. mSimb <= 239
                   cFileName = "Rus Lower "+ConvToAnsiCP(CHR(mSimb))+".bmp"     // Чтобы в именах файлов можно было использовать русские символы
                ENDIF
             ENDIF
          ENDIF
       ENDIF

       IF cFileName <> "No name"                                                // Чтобы не записывать изображений, которые не нужно

          *** Стереть окно, т.е. нарисовать белый прямоугольник с белыми границами
          GraSetColor( oPS, GRA_CLR_WHITE, GRA_CLR_WHITE )
          GraBox( oPS, { 0, 0 }, { X_MaxW, Y_MaxW }, GRA_FILL ) 
          GraSetColor( oPS, GRA_CLR_BLACK, GRA_CLR_BLACK )

          aTxtPar = DC_GraQueryTextbox(CHR(mSimb), oFont)                       // {101,16} Определяет длину и высоту текста в пикселях для некоторых шрифтов
          GraStringAt( oPS, { 0, 0 }, CHR(mSimb))                               // Отобразить символ
          ERASE( cFileName );DC_Scrn2ImageFile( oStatic, cFileName )            // Стереть старый файл и записать новый
*         MsgBox(cFileName+". Длина текста: "+CHR(mSimb)+" в пикселях="+ALLTRIM(STR(aTxtPar[1]))+". Высота текста в пикселях="+ALLTRIM(STR(aTxtPar[2])))

       ENDIF
   NEXT

*  DIRCHANGE(Disk_dir)
   DIRCHANGE('..')

   LB_Warning( "Процесс генерации изображений символов завершен успешно!", "АСК-анализ изображений" )

RETURN NIL


******** Display a warning message
******** Может выдавать сообщения элементами массива и без ctitle:

*message := {}
*AADD(message,'1-е сообщение')
*AADD(message,'2-е сообщение')
*AADD(message,'3-е сообщение')
*LB_Warning( message )

FUNCTION LB_Warning( message, ctitle )

  LOCAL aMsg := {}
  DEFAULT cTitle TO ''
  IF valtype(message) # 'A'
    aadd(aMsg,message)
  ELSE
    aMsg := message
  ENDIF
  IF LEN(ALLTRIM(cTitle)) > 0
     DC_MsgBox( ,,aMsg,cTitle)
  ELSE
     DC_MsgBox( ,,aMsg,'(C) Универсальная когнитивная аналитическая система "Эйдос-Х++"')
  ENDIF

RETURN NIL
*******************************************************
[/size]

Re: Generating and saving images of characters

Posted: Wed Jul 08, 2015 9:59 am
by Eugene Lutsenko
I would like to in the above image generator of characters:
1. First, determine the minimum area required to reach the image of characters (I did).
2. And then keep all the character images generated in this area (without extra pixels).
This is similar to the operation "trimming". For this I would like to take advantage of features Roger, which showcased the work of the program:

Code: Select all

#pragma library( "dclip1.lib" )
#pragma library( "dclip2.lib" )
#pragma library( "dclipx.lib" )

STATIC snHdll

FUNCTION Main()

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

@ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP ;
      CAPTION "colors.jpg" ;
      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.jpg" ;
      PREEVAL {|o|o:autoSize := .t.} ;
      OBJECT oStatic2 ;
      EVAL {|o|hDC2 := GetWindowDC(o:getHWnd())}

@ 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 + 20 DCPUSHBUTTON CAPTION 'Transfer Image' ;
    SIZE 80,20 ACTION {||TransferImage(hDC1,hDC2,aPixel)}

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

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

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Load Array' ;
    SIZE 80,20 ACTION {||LoadArray(hDC1,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
[/size]
I would particularly like to image generators use the characters: GetPixel().
It is necessary not to open a new window, and open the previously used to create an image. Desirably, the execution of the program to be stopped is not dialogue.

Re: Generating and saving images of characters

Posted: Thu Jul 09, 2015 12:00 pm
by Eugene Lutsenko
Some of the things that would happen. I hope soon to show some result. Only a little of this in my time ...

Re: Generating and saving images of characters

Posted: Thu Jul 09, 2015 1:36 pm
by Eugene Lutsenko
It can function SetPixel() to work with the same graphic file hDC1, that GetPixel()?
This is me trying to look for the left border of the image.

Code: Select all

   X1 = -999
   FOR x = 1 TO nXSize
       FOR y = 1 TO nYSize
           mPix = GetPixel(hDC1, x-1, y-1)
*          MsgBox("x="+STR(x)+", y="+STR(y)+",  mPix="+STR(mPix))
*          GraArc( oPS, { x-1, y-1 }, 1, ,,, GRA_OUTLINEFILL )
           SetPixel(hDC1, x-1, y-1, fColor)
           IF mPix <> -1
              X1 = x
              EXIT
           ENDIF
       NEXT
   NEXT
[/size]

Re: Generating and saving images of characters

Posted: Thu Jul 09, 2015 9:26 pm
by Eugene Lutsenko
Hi!
I tried (unsuccessfully) to identify and map the boundaries of the total image area of all the characters. I tried (unsuccessfully) to identify and map the boundaries of the image of each character (outline).
http://lc.kubagro.ru/Dima/outline.rar
There is an impression that the function GetPixel() gives an error value of the pixel (always == -1).
The function SetPixel() also failed in the use of my program and instead I used GraMarker().
Although, of course, Roger program it works. Now, if Roger is still made to display not only the coordinates of the mouse cursor, and the pixel value returned by GetPixel().

Added to the program Roger contouring and trimming.
Image
Everything worked out. And in my program generating character images is to do it can not.
We also define the minimum sufficient area for the image. Another would be to save as a graphic image file, circled in blue frame, ie, image area.

Re: Generating and saving images of characters

Posted: Wed Jul 15, 2015 9:54 pm
by Eugene Lutsenko
Hi, Roger!

I started to use your graphics in your system. In general, it turns out, but the questions remain. I'd like to display images on the screen your way:

Code: Select all

   FOR mImg = 1 TO LEN(aFileName)

       @ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP ;
             CAPTION aFileName[mImg] ;
             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 aFileName[mImg] ;
             PREEVAL {|o|o:autoSize := .t.} ;
             OBJECT oStatic2 ;
             EVAL {|o|hDC2 := GetWindowDC(o:getHWnd())}

       DCGETOPTIONS PIXEL

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


       *** Вызов функций в стиле Роджера
       *** Для формирования БД Inp_data.dbf




       *** Определение контуров (если задано)

   NEXT
[/size]
It is necessary to analyze the sequence of images. But with this method image display is stopped after each image. The process is going on just by pressing a key. And I would like to take the process without user intervention.

The way in which you brought up, works well, but not on your graphic example:

rdonnay wrote:I made a few changes to your code.

1. You don't need all those #include files and libraries.

All you need are these:

Code: Select all

#INCLUDE "dcdialog.CH"
#INCLUDE "common.CH"
#INCLUDE "appevent.CH"

#pragma library( "dclipx.lib" )
#pragma library( "xbtbase1.lib" )
#pragma library( "xbtbase2.lib" )
2. Change the functioin DrawSimbol to the following:

Code: Select all

FUNCTION DrawSimbol( cFont)

   LOCAL GetList := {}, oStatic

   PRIVATE nEvent, mp1, mp2, oXbp                      // ¥à¥¬¥­­ë¥  ­ «¨§  ᮡë⨩

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                //  §¬¥à £à ä¨ç¥áª®£® ®ª­  ¤«ï á ¬®£® £à ä¨ª  ¢ ¯¨ªá¥«ïå

   cFont   =     FileStr('_Font.txt')

   @ 2,1 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX SIZE X_MaxW+11, Y_MaxW+20 PIXEL; //  §¬¥à ®ª­  ¢ ¯¨ªá¥«ïå (®â ’®¬ )
         OBJECT oStatic;

   DCREAD GUI ;
      TITLE "¨á®¢ ­¨¥ ¨§®¡à ¦¥­¨© ᨬ¢®«®¢ ¢ á¨á⥬¥ ‰„Ž‘-X++";   //  ¤¯¨áì ­  ®ª­¥ £à ä¨ª 
      FIT ;
      EVAL {|o| _PresSpaceSimbol( oStatic, cFont), ;
              PostAppEvent(xbeP_Close,,,o) }

RETURN NIL
3. Change the function _PresSpaceSimbol to the following:

Code: Select all

STATIC FUNCTION _PresSpaceSimbol( oStatic, cFont )

   LOCAL oPS, oDevice

   cFont   =     FileStr('_Font.txt')

   PUBLIC X_MaxW := 1313, Y_MaxW := 640                //  §¬¥à £à ä¨ç¥áª®£® ®ª­  ¤«ï á ¬®£® £à ä¨ª  ¢ ¯¨ªá¥«ïå

   oPS := XbpPresSpace():new()         // Create a PS
   oDevice := oStatic:winDevice()      // Get the device context
   oPS:create( oDevice )               // Link device context to PS
   oPS:SetViewPort( { 0, 0, X_MaxW, Y_MaxW } )
   // oStatic:paint := {|mp1,mp2,obj| mp1 := LC_DrawSimbol( oPS, oStatic, cFont ) }
   LC_DrawSimbol( oPS, oStatic, cFont )

RETURN NIL
[/size]
Could you as a way to modify your output (shown at the beginning of the post), the process of displaying the sequential images was non-stop.

Also now I need an area for the modified image:

        @ 0,250 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP;
              CAPTION aFileName [mImg];
              PREEVAL {| o | o: autoSize: = .t.};
              OBJECT oStatic2;
              EVAL {| o | hDC2: = GetWindowDC (o: getHWnd ())}

But if it does not display, the errors and display the original image.