I would like to use your program for the development of graphics technology: all the necessary operations to modify images.
As for the windows, I put it accurately. I would like to. to both images: the original and transformed, were in the same window. This single window is divided in the middle into two parts: the left side - the original image, and the right - modified. Each image in the center of the field.
I have done to modify the image displayed on the center right of the window (and the height and width). But do not know how to do to the original image is displayed in the center of the left side (and on the height and width).
Of course the mouse should show the coordinates and color of the pixels to the original image. While this is not the case (source program was all right).
While the modified program Roger I's what happened (the source code below). Something happened, and something - no.
Yet for some reason, this topic is not always displayed on the forum, but the link is launched.
Code: Select all
**************************************************************************************************
**************************************************************************************************
#pragma library( "dclip1.lib" )
#pragma library( "dclip2.lib" )
#pragma library( "dclipx.lib" )
#pragma library( "xbtbase1.lib" )
#pragma library( "xbtbase2.lib" )
STATIC snHdll
FUNCTION Main()
LOCAL GetList[0], GetOptions, oSay, hDC1, hDC2, oStatic1, oStatic2, ;
aPixel
DC_IconDefault(1000)
PUBLIC X_MaxW := 1313, Y_MaxW := 640 // Размер графического окна для изображения в пикселях (чтобы помещалось на ультрабук)
*mNameImage = 'Eng_Upper_A.jpg'
mNameImage = 'Eng Upper A.bmp'
@ 0,0 DCSTATIC TYPE XBPSTATIC_TYPE_BITMAP SIZE X_MaxW+11, Y_MaxW+20 PIXEL;
CAPTION mNameImage ;
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 SIZE X_MaxW+11, Y_MaxW+20 PIXEL;
CAPTION mNameImage ;
PREEVAL {|o|o:autoSize := .t.} ;
OBJECT oStatic2 ;
EVAL {|o|hDC2 := GetWindowDC(o:getHWnd())}
@ Y_MaxW,900 DCSAY 'Координаты курсора мыши: ' SAYSIZE 350,20 FONT '10.Lucida Console' OBJECT oSay // Позиция для отображения координат пикселя положения курсора мыши
@ Y_MaxW,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 'Spectrum Spiral' ; // Моя первая пиксельная функция
SIZE 100,20 ACTION {||SpectrumSpiral(hDC2,aPixel)}
@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'Load Array' ;
SIZE 80,20 ACTION {||LoadArray(hDC1,aPixel)}
DCGETOPTIONS PIXEL
DCREAD GUI FIT TITLE 'Исследование изображений в системе "Эйдос-Х++"' OPTIONS GetOptions ;
EVAL {||ClearImage(hDC2,aPixel)}
RETURN nil
* ---------
FUNCTION LoadArrayOld( 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 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()
X0R = X_MaxW * 3 / 4 // Для правого изображения
Y0R = Y_MaxW / 2
FOR i := 1 TO nXSize
FOR j := 1 TO nYSize
aPixel[i,j] := GetPixel(hDC1,X0R+i-1-nXSize/2,Y0R+j-1-nYSize/2)
NEXT
NEXT
DC_Impl(oScrn)
RETURN nil
* ---------
FUNCTION ClearImageOld( 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 ClearImage( hDC2, aPixel )
LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
LOCAL nColor := AutomationTranslateColor(GraMakeRGBColor({255,255,255}),.f.)
X0R = X_MaxW * 3 / 4 // Для правого изображения
Y0R = Y_MaxW / 2
FOR i := 0 TO nXSize
FOR j := 0 TO nYSize
SetPixel(hDC2, X0R+i-nXSize/2, Y0R+j-nYSize/2, nColor)
NEXT
NEXT
RETURN nil
* ---------
FUNCTION SpectrumSpiral( hDC2, aPixel )
LOCAL i, j, nXSize := Len(aPixel), nYSize := Len(aPixel[1])
*** Расчет позиций центров изображений в стилях "Контур" и "Витраж"
Dx = 50
Dy = 30
* mRadiusMax = MAX(nXSize, nYSize)
mRadiusMax = X_MaxW / 4
Ax = ( X_MaxW - 2 * Dx ) / ( 2 * mRadiusMax )
Ay = ( Y_MaxW - 2 * Dy ) / ( 2 * mRadiusMax )
Dx = ( X_MaxW - 2 * mRadiusMax ) / 2
Dy = ( Y_MaxW - 2 * mRadiusMax ) / 2
X0L = X_MaxW / 4 // Для левого изображения
Y0L = Y_MaxW / 2
X0R = X_MaxW * 3 / 4 // Для правого изображения
Y0R = Y_MaxW / 2
****** Гармонические последовательности цветов
Column = 0
Ax = 0.05
Ay = 0.05
Kx = 1
Ky = 1
FOR n = 0 TO 360*50 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 / 4 <= X1 .AND. X1 <= X0R + X_MaxW / 4
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 TransferImageOld( 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 TransferImage( hDC1, hDC2, aPixel )
LOCAL i, j, nColor, lEmptyArray := aPixel[1,1] == nil, ;
nXSize := Len(aPixel), nYSize := Len(aPixel[1])
X0R = X_MaxW * 3 / 4 // Для правого изображения
Y0R = Y_MaxW / 2
FOR i := 0 TO nXSize-1
FOR j := 0 TO nYSize-1
IF lEmptyArray
SetPixel(hDC2,X0R+i-nXSize/2, Y0R+j-nYSize/2, GetPixel(hDC1, X0R+i-nXSize/2, Y0R+j-nYSize/2))
ELSE
SetPixel(hDC2, X0R+i-nXSize/2, Y0R+j-nYSize/2, 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
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,nYSize-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
*******************************************************************************
*******************************************************************************
* Calculates a RGB color value from RGB color intensities
*******************************************************************************
FUNCTION GraMakeRGBColor( aRGB )
IF Valtype( aRGB ) <> "A" .OR. ;
Len( aRGB ) < 3 .OR. ;
AScan( aRGB, {|n| Valtype(n) <> "N" }, 1, 3 ) > 0
RETURN NIL
ENDIF
aRGB[1] := Max( 0, Min( aRGB[1], 255 ) )
aRGB[2] := Max( 0, Min( aRGB[2], 255 ) )
aRGB[3] := Max( 0, Min( aRGB[3], 255 ) )
RETURN (aRGB[1] + (aRGB[2] * 256) + (aRGB[3] * 65536) + 16777216)
*******************************************************************************
* Check if a numeric value is equivalent to a RGB-color value
*******************************************************************************
FUNCTION GraIsRGBColor( nRGBColor )
IF Valtype( nRGBColor ) <> "N"
RETURN .F.
ENDIF
RETURN ( nRGBColor > GRA_NUMCLR_RESERVED .AND. nRGBColor - 16777216 >= 0 )
*******************************************************************************
* Check if a numeric value is equivalent to a RGB-color value
*******************************************************************************
FUNCTION GraGetRGBIntensity( nRGBColor )
LOCAL aRGB[3]
IF .NOT. GraIsRGBColor( nRGBColor )
RETURN NIL
ENDIF
aRGB[1] := nRGBColor - 16777216
aRGB[3] := Int(aRGB[1] / 65536)
aRGB[1] -= aRGB[3] * 65536
aRGB[2] := Int(aRGB[1] / 256)
aRGB[1] -= aRGB[2] * 256
RETURN aRGB
*******************************************************************************
**********************************************
******** ВИЗУАЛИЗАЦИЯ СПЕКТРА ****************
**********************************************
FUNCTION DrawSpectr(mNGrad)
PRIVATE nEvent, mp1, mp2, oXbp // Переменные анализа событий
PUBLIC X_MaxW := 1313, Y_MaxW := 640 // Размер графического окна для самого графика в пикселях
@ 2,1 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX SIZE X_MaxW+11, Y_MaxW+20 PIXEL; // Размер окна в пикселях (от Тома)
OBJECT oStatic;
EVAL {|| _PresSpaceSpectr(oStatic, mNGrad) }
DCREAD GUI ;
TITLE "Рисование спектра в системе ЭЙДОС-X++"; // Надпись на окне графика
FIT ;
BUTTONS DCGUI_BUTTON_EXIT
RETURN NIL
*************************************************
STATIC FUNCTION _PresSpaceSpectr( oStatic, mNGrad )
LOCAL oPS, oDevice
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_DrawSpectr( oPS, mNGrad ) }
RETURN NIL
*******************************************************
STATIC FUNCTION LC_DrawSpectr(oPS, mNGrad )
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 // Высота окна для самого графика
PRIVATE Kx := W_Wind / ( mNGrad ) // Коэффициент масштабирования по оси X: преобразует аргумент функции в номер пикселя по оси X
PRIVATE Ky := H_Wind / ( mNGrad ) // Коэффициент масштабирования по оси Y: преобразует значение функции в номер пикселя по оси Y
**** Написать заголовок диаграммы
aFonts := XbpFont():new():list() // Все доступные шрифты
oFont := XbpFont():new():create("14.Arial Bold")
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 = 'СПЕКТР ИЗ '+ALLTRIM(STR(mNGrad))+' ЦВЕТОВ В ФОРМЕ СПИРАЛИ АРХИМЕДА'
aTxtPar = DC_GraQueryTextbox(mTitle, oFont) // {101,16} Определяет длину и высоту текста в пикселях для некоторых шрифтов
* MsgBox("Длина текста в пикселях="+ALLTRIM(STR(aTxtPar[1]))+". Высота текста в пикселях="+ALLTRIM(STR(aTxtPar[2])))
GraStringAt( oPS, { X_MaxW/2, Y_MaxW+aTxtPar[2]+5 }, mTitle)
******* Гармонические последовательности цветов
Column = 0
FOR n = mNGrad TO mNGrad * 60 / 360 STEP -Delta
ma := 127
mb := 127
mc := 127
mU := 0
mV := 120
mW := 240
mColor = INT( n / mNGrad * 360 )
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( oPS, fColor, fColor )
Column = Column + Delta
X1 := X0 + Ax * Column * COS((Column-1) * 3.14159265358979323846 / 180 ) * Kx
Y1 := Y0 + Ay * Column * SIN((Column-1) * 3.14159265358979323846 / 180 ) * Ky
GraArc( oPS, { X1, Y1 }, RS, ,,, GRA_OUTLINEFILL )
NEXT
cFileName = ConvToAnsiCP("Спектр в форме спирали.bmp")
DC_Scrn2ImageFile( oStatic, cFileName )
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
*******************************************************