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
Croping a BMP image
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Rafael,
Its not difficult to do it. Basically it may do:
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
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
It doesn't work (I get a black bitmap). What am I doing wrong?
EMG
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
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- RAMESHBABU
- Posts: 591
- Joined: Fri Oct 21, 2005 5:54 am
- Location: Secunderabad (T.S), India
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
**********
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
**********
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
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:
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
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain