Passing a bitmap to DLL using handle to it

Hello experts :-)

I need to pass a bitmap to a dll, edit it there and then send to back.

I know (thank you ziolko :-) ) how to do it using (Buffer : Pointer; StreamLength : Int64).

However, I was told that it is possible to pass a handle to bitmap to DLL and make it this way.

Question: how can I do it?

Polon
panJamesAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
ziolkoConnect With a Mentor Commented:
slightly changed DLL so there's no memory leak:

library BMPDLL;

uses
  SysUtils,
  Classes,
  Windows,
  Graphics;

{$R *.res}

var TmpBMP: TBitmap;

procedure MakeColorAnalysis3(var Bitmap: HBITMAP);stdcall;
var bmp: TBitmap;
begin
  bmp := TBitmap.Create;
  try
    bmp.Handle := Bitmap;
    with TmpBMP do begin
      Assign(bmp);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(256, 256);
      Bitmap := Handle;
    end;
  finally
    bmp.Free;
  end;  
end;

procedure OnDLLLoad;
begin
  TmpBMP := TBitmap.Create;  
end;

procedure OnDLLUnLoad;
begin
  FreeAndNil(TmpBMP);
end;

procedure MyDLLProc(dwReason: Integer);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:   OnDLLLoad;
    DLL_PROCESS_DETACH:   OnDLLUnLoad;
  end;
end;

exports
  MakeColorAnalysis3;

begin
  DllProc := MyDLLProc;
  DllProc(DLL_PROCESS_ATTACH);
end.

ziolko.
0
 
MerijnBSr. Software EngineerCommented:
do you write the dll yourself?
0
 
developmentguruConnect With a Mentor PresidentCommented:
The TBitmap has a handle property and this is the handle that Windows recognizes as the bitmap.  Passing this hanlde should be what you are looking for.  If you are writing the DLL yourself then you can create a TBitmap object and assign the handle to it.  You should then be able to edit it via the bitmap object's canvas property as usual.  The attached code shows an example (without the dll).  Place 2 paint boxes and a button on a form.  Paste in the code and attach the paint boxes OnPaint methods, form create and destroy methods, and the button click method.  The form creates a bitmap and draws to it.  When you click the button it copies the handle from the drawn bitmap to the as yet untouched bitmap then invalidates the second paint box to show you the result.

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;
 
type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    PaintBox2: TPaintBox;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure PaintBox2Paint(Sender: TObject);
  private
    { Private declarations }
    Bitmap1, Bitmap2 : TBitmap;
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Bitmap2.Handle := Bitmap1.Handle;
  PaintBox2.Invalidate;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Bitmap1 := TBitmap.Create;
  with Bitmap1, Canvas do
    begin
      Width := 100;
      Height := 100;
      Brush.Color := clBlue;
      FillRect(Rect(0, 0, 99, 99));
    end;
  Bitmap2 := TBitmap.Create;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  Bitmap1.Free;
  Bitmap2.Free;
end;
 
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  R : TRect;
 
begin
  R := Rect(0, 0, 99, 99);
  PaintBox1.Canvas.CopyRect(R, Bitmap1.Canvas, R);
end;
 
procedure TForm1.PaintBox2Paint(Sender: TObject);
var
  R : TRect;
 
begin
  R := Rect(0, 0, 99, 99);
  PaintBox2.Canvas.CopyRect(R, Bitmap2.Canvas, R);
end;
 
end.

Open in new window

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
developmentguruPresidentCommented:
I modified the contents of the button click event to draw to the second bitmap and show that both update...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Bitmap2.Handle := Bitmap1.Handle;
  with Bitmap2, Canvas do
    begin
      MoveTo(0, 0);
      LineTo(99, 99);
    end;
  PaintBox1.Invalidate;
  PaintBox2.Invalidate;
end;

Open in new window

0
 
ziolkoCommented:
I'm afraid that's not what you looking for but that's best solution I've come up with

library BMPDLL;

uses
  SysUtils,
  Classes,
  Windows,
  Graphics;

{$R *.res}

procedure MakeColorAnalysis3(var Bitmap: HBITMAP);stdcall;
var bmp: TBitmap;
begin
  bmp := TBitmap.Create;
  try
    bmp.Handle := Bitmap;
    with TBitmap.Create do begin
      Assign(bmp);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(256, 256);
      Bitmap := Handle;
    end;
  finally
    bmp.Free;
  end;  
end;

exports
  MakeColorAnalysis3;

begin
end.

EXE:
interface
procedure MakeColorAnalysis3(var Bitmap: HBITMAP);stdcall;
implementation
procedure MakeColorAnalysis3;external 'bmpdll.dll' name 'MakeColorAnalysis3';

procedure TForm1.Button6Click(Sender: TObject);
var h: HBITMAP;
begin
  h := Image1.Picture.Bitmap.Handle;
  MakeColorAnalysis3(h);
  Image1.Picture.Bitmap.Handle := h;
end;

ziolko.
0
 
ziolkoCommented:
I've also found some C++ code that supposedly lets you access raw bmp bits represented by HBITMAP (so there's no need to create additional bmp in DLL and re-assign Handle on EXE side) but can't make it work all I got is scrambled image.

ziolko.
0
 
ziolkoCommented:
 with TmpBMP do begin
      ReleaseHandle;    
      Assign(bmp);
      Canvas.MoveTo(0, 0);

ziolko.
0
 
ziolkoCommented:
any progress on this one?


ziolko.
0
All Courses

From novice to tech pro — start learning today.