Page 1 of 1
Croping a BMP image
Posted: Fri Mar 31, 2006 10:14 am
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
Posted: Fri Mar 31, 2006 12:25 pm
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
Posted: Fri Mar 31, 2006 12:58 pm
by Rafael Clemente
Thanks a lot, Antonio. Looks quite easy...
Rafael
Posted: Fri Mar 31, 2006 6:19 pm
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
Posted: Fri Mar 31, 2006 6:53 pm
by Antonio Linares
Enrico,
We may be missing something...
Posted: Sat Apr 01, 2006 2:47 am
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
**********
Posted: Sat Apr 01, 2006 8:23 am
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
Posted: Sat Apr 01, 2006 10:26 am
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