Croping a BMP image

Post Reply
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Croping a BMP image

Post by Rafael Clemente »

Anybody has a function to perform croping of a rectangular section in a BMP file? Something like this: Crop(cBmpFile, aRect) with aRect being the coordinates in pixels.

I know that it can be done using NConvert.exe, but I would like to include the function in my program, without havint to resort to an external executable

Thanks,

Rafael
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Rafael,

Its not difficult to do it. Basically it may do:

Code: Select all

function Crop( cBmpFile, nTop, nLeft, nWidth, nHeight )

   local hDC1   := GetDC( 0 )
   local hBmp1 := ReadBitmap( hDC, cBmpFile )
   local hDC2   := CreateCompatibleDC( hDC1 )
   local hBmp2 := CreateCompatibleBitmap( hDC2, nWidth, nHeight )
   local hBmpOld1 := SelectObject( hDC1, hBmp1 )
   local hBmpOld2 := SelectObject( hDC2, hBmp2 )

   BitBlt( hDC2, 0, 0, nWidth, nHeight, hDC1, nLeft, nTop, SRCCOPY )

   ...

At that point, hBmp2 is a bitmap with the portion of the image that you want. You may save it to disk or use it for painting.     
   
   ...

   SelectObject( hDC1, hBmpOld1 )
   SelectObject( hDC2, hBmpOld2 )
   ReleaseDC( 0, hDC1 )
   DeleteDC( hDC2 )

return nil   
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Thanks a lot, Antonio. Looks quite easy...
Rafael
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Post by Enrico Maria Giordano »

It doesn't work (I get a black bitmap). What am I doing wrong?

Code: Select all

#include "Fivewin.ch"


FUNCTION MAIN()

    LOCAL oDlg

    LOCAL hBmp := CROP( "c:\fwharbour\bitmaps\magic.bmp", 100, 100, 100, 50 )

    DEFINE DIALOG oDlg

    ACTIVATE DIALOG oDlg;
             ON PAINT PALBMPDRAW( hDC, 0, 0, hBmp );
             CENTER

    RETURN NIL


#define SRCCOPY 13369376


FUNCTION CROP( cBmpFile, nTop, nLeft, nWidth, nHeight )

    LOCAL hDC1  := GETDC( 0 )
    LOCAL hBmp1 := READBITMAP( hDC1, cBmpFile )
    LOCAL hDC2  := CREATECOMPATIBLEDC( hDC1 )
    LOCAL hBmp2 := CREATECOMPATIBLEBITMAP( hDC2, nWidth, nHeight )

    LOCAL hBmpOld1 := SELECTOBJECT( hDC1, hBmp1 )
    LOCAL hBmpOld2 := SELECTOBJECT( hDC2, hBmp2 )

    BITBLT( hDC2, 0, 0, nWidth, nHeight, hDC1, nLeft, nTop, SRCCOPY )

    SELECTOBJECT( hDC1, hBmpOld1 )
    SELECTOBJECT( hDC2, hBmpOld2 )
    RELEASEDC( 0, hDC1 )
    DELETEDC( hDC2 )

    RETURN hBmp2


#pragma BEGINDUMP

#include "windows.h"
#include "hbapi.h"


HB_FUNC( CREATECOMPATIBLEDC )
{
    hb_retnl( ( LONG ) CreateCompatibleDC( ( HDC ) hb_parnl( 1 ) ) );
}


HB_FUNC( CREATECOMPATIBLEBITMAP )
{
    hb_retnl( ( LONG ) CreateCompatibleBitmap( ( HDC ) hb_parnl( 1 ), hb_parni( 2 ), hb_parni( 3 ) ) );
}

#pragma ENDDUMP
EMG
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Enrico,

We may be missing something...
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
RAMESHBABU
Posts: 591
Joined: Fri Oct 21, 2005 5:54 am
Location: Secunderabad (T.S), India

Post by RAMESHBABU »

Mr.Rafael

This is the working sample to Crop a Bitmap to the required size.
This program is simplified version of "TESTBMP.PRG" to demonstrate
your particular requirement.

Regards,

- Ramesh Babu P


#include "Fivewin.ch"

static bmpFish, aCoors := {10,10,135,240} // Your Coordinates

FUNCTION main()

local oDlg
local n := 1

#ifndef __CLIPPER__
SET RESOURCES TO "Fishes32.dll" // 32 bits DLL version
#else
SET RESOURCES TO "Fishes16.dll" // 16 bits DLL version for Clipper users
#endif

DEFINE DIALOG oDlg RESOURCE "Fish"

REDEFINE BITMAP bmpFish ID 110 OF oDlg NAME "Fish1"

*bmpFish:bLDblClick = { | nRow, nCol, nFlags | ;
* MsgInfo( "DblClick on the bitmap" ) }

bmpFish:bLDblClick = { ||Crop(bmpfish, aCoors)}

REDEFINE BUTTON ID 120 OF oDlg ;
ACTION If( n > 1, bmpFish:SetBMP( "Fish" + AllTrim( Str( --n ) ) ), ;
Tone( 956, 2 ) )

REDEFINE BUTTON ID 130 OF oDlg ;
ACTION If( n < 6, bmpFish:SetBMP( "Fish" + AllTrim( Str( ++n ) ) ), ;
Tone( 956, 2 ) )

ACTIVATE DIALOG oDlg CENTERED


return nil

*******************************************************************************
*** FUNCTION Crop(oBmp,aCoors) to Crop the Bitmap to the required Coordinates ***
*******************************************************************************

FUNCTION Crop(oBmp, aCoors)

oBmp:nTop := aCoors[1]
oBmp:nLeft := aCoors[2]
oBmp:nBottom := aCoors[3]
oBmp:nRight := aCoors[4]

oBmp:Box(oBmp:nTop, oBmp:nLeft, oBmp:nBottom, oBmp:nRight)

DibWrite( "crop.bmp", DibFromBitmap( wnd_bitmap( oBmp:hWnd,;
oBmp:nTop, oBmp:nLeft, oBmp:nBottom+1, oBmp:nRight+1 ) ) )

oBmp:LoadBMP("crop.bmp")

oBmp:Refresh()

// ERASE crop.bmp

RETURN nil

**********
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Enrico,

Just pure curiosity, but we should discover whats wrong with the code :)

This little sample works ok and paints a portion of the bitmap. So we may probably need to use one more hDC:

Code: Select all

#include "Fivewin.ch" 

#define SRCCOPY 13369376 

function Main() 

   local oDlg, hBmp := ReadBitmap( 0, "..\bitmaps\magic.bmp" )
    
   DEFINE DIALOG oDlg 

   ACTIVATE DIALOG oDlg; 
      ON PAINT DrawBitmap( hDC, hBmp, 0, 0, 100, 100 ) ;
      CENTER

return nil

static function DrawBitmap( hDC, hBmp, nTop, nLeft, nWidth, nHeight ) 

   local hDC1     := CreateCompatibleDC( hDC )
   local hBmpOld1 := SelectObject( hDC1, hBmp ) 

   BitBlt( hDC, 0, 0, nWidth, nHeight, hDC1, nLeft, nTop, SRCCOPY )

   SelectObject( hDC1, hBmpOld1 ) 
   DeleteDC( hDC1 ) 

return nil

#pragma BEGINDUMP 

#include "windows.h" 
#include "hbapi.h" 

HB_FUNC( CREATECOMPATIBLEDC ) 
{ 
   hb_retnl( ( LONG ) CreateCompatibleDC( ( HDC ) hb_parnl( 1 ) ) ); 
} 

#pragma ENDDUMP
Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Antonio's sample is working fine. Now, to round it up: how to save the cropped image to disk? Sorry for such a dumb question, but I still have to come to terms with all this stuff of Device Contexts and so on...
Thanks
Rafael
Post Reply