FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Image Crop
Posts: 990
Joined: Thu Nov 17, 2005 05:49 PM
Image Crop
Posted: Thu May 07, 2009 06:29 PM
Hi.

Using function RectDotted( ::hWnd, ::nBoxTop, ::nBoxLeft, ::nBoxBottom, ::nBoxRight ), I've been able to draw a dotted rectangle on a timage being displayed on a window. I need to find a way to keep only this portion of the image. To this end I saw an idea using WndCopy4( ::hWnd, aRect ). But that copies the rectangle from the screen where the resolution might not be as good as the original bmp/jpg being displayed.

Can someone point me in the right direction as to how to read the selected rectangle from the bmp/jpg file instead of from the screen?

Here is the code I've been using:
Code (fw): Select all Collapse
//----------------------------------------------------------------------------//

METHOD LButtonDown( nRow, nCol, nFlags ) CLASS TImage

    if ::bLClicked != nil
        Eval( ::bLClicked, nRow, nCol, nFlags )
    else
        ::lBoxDraw   = .t.
        ::nBoxTop    = nRow
        ::nBoxLeft   = nCol
        ::nBoxBottom = nRow
        ::nBoxRight  = nCol
        ::Capture()
        ::DrawBox()
    endif

return nil


//----------------------------------------------------------------------------//

METHOD MouseMove( nRow, nCol, nFlags ) CLASS TImage

    if ::lBoxDraw
        ::DrawBox()     //deletes existing dottedbox

        ::nBoxBottom    := iif( ::nBoxBottom < nRow, nRow, ::nBoxBottom )
        ::nBoxRight := iif( ::nBoxRight < nCol, nCol, ::nBoxRight )

        ::nBoxTop       := iif( ::nboxTop > nRow, nRow, ::nboxTop )
        ::nBoxLeft      := iif( ::nBoxLeft > nCol, nCol, ::nBoxLeft )
      
        ::DrawBox()     //redraws new dottedbox

    endif

return Super:MouseMove( nRow, nCol, nFlags )

//----------------------------------------------------------------------------//

METHOD LButtonUp( nRow, nCol, nFlags ) CLASS TImage2

   if ::lBoxDraw .and. ::nBoxTop <> ::nBoxBottom .and. ::nBoxLeft <> ::nBoxRight
        ::DrawBox()
        ::CopyRect( { ::nBoxTop, ::nBoxLeft, ::nboxBottom, ::nBoxRight } )
        ReleaseCapture()

        DrawFocusRect( ::hdc, { ::nBoxTop, ::nBoxLeft, ::nboxBottom, ::nBoxRight } )

        ::ScrollAdjust()
        ::refresh( .t. )
    endif

    ::lBoxDraw = .f.

return nil


*-------------------------------------------------------------------------------------------------------------------------------
METHOD CopyRect( aRect ) CLASS TImage2
local hBmp := WndCopy4( ::hWnd, aRect )
Local cFile:= Temp_Name( "bmp" )

    DibWrite( cfile, DibFromBitmap( hBmp ) )
    DeleteObject( hBmp )
    ::loadImage( ,cfile)
    ::refresh()
    ferase( cfile )

return nil


Thank you,


Reinaldo.
Posts: 4043
Joined: Wed Dec 19, 2007 06:40 PM
Re: Image Crop
Posted: Thu May 07, 2009 09:06 PM
Hello Reinaldo,

if there will be a possible solution, it will help Silvio as well with his problem.

viewtopic.php?f=3&t=15397

Regards
Uwe :-)
Since 1995 ( the first release of FW 1.9 )

i work with FW.

If you have any questions about special functions, maybe i can help.
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
Re: Image Crop
Posted: Thu May 07, 2009 09:14 PM

Hi Reinaldo,

I don't know the answer, but here are some ideas. You will need to find the relation between the screen size and the image size and then calculate the new coordiates of the box for the image size. Then perhaps you can redraw the image full size in another window which you draw offscreen (so the user doesn't see it). Then use the same WndCopy4() that you are using now.

This is not a good solution, but it make work until you can find a better one.

Regards,
James

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 990
Joined: Thu Nov 17, 2005 05:49 PM
Re: Image Crop
Posted: Thu May 07, 2009 09:21 PM
The code I currently have will probably solve Sivio's needs. The only method missing in my code was the drawbox method. Here it is:

Code (fw): Select all Collapse
    
METHOD DrawBox() Class TImage

    RectDotted( ::hWnd, ::nBoxTop, ::nBoxLeft, ::nBoxBottom, ::nBoxRight )

Return Nil


All you need to test these methods is to create this class inheriting from timage. Load a picture on a window/dialog and see it work. It works fine. But it selects the pixels on the picture from the display image not from the original jpg file, thus you could loose resolution.

Reinaldo.
Posts: 990
Joined: Thu Nov 17, 2005 05:49 PM
Re: Image Crop
Posted: Thu May 07, 2009 10:16 PM
James;

Thank you for the reply.

I was hoping that someone had already done the work to do exactly that calculation. As it turns out, freeimage already has a function to crop a jpg:

Code (fw): Select all Collapse
DLL32 FUNCTION FI_JpgCrop( cSource AS LPSTR, ;
                            cDest AS LPSTR, ;
                            nLeft AS LONG, ;
                            nTop AS LONG, ;
                            nRight AS LONG, ;
                            nBottom AS LONG ) AS BOOL ;
PASCAL FROM "_FreeImage_JPEGCrop@24" LIB hLib


Now I suspect that all I need is to calculate from the dialog's resolution to the actual jpg resolution to then supply nlef, ntop, nrigh, and nbottom.


Reinaldo.
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
Re: Image Crop
Posted: Thu May 07, 2009 10:44 PM

Reinaldo,

Here is a start:

aRec := oWnd:getCliRect()
nWndWidth:= aRec[4] - aRec[2]
nWndHeight:= aRec[3]- aRec[1]

nWidthRatio := nImageWidth/nWndWidth
nHeightRatio := nImageHeight/nWndHeight

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10

Continue the discussion