Converter Bitmap para Memory Mapped File

Delphi

03/10/2005

Olá pessoal,

Estou com um problemasso em uma de minhas aplicações. Tenho um componente integrado com minha aplicação que faz algumas manipulações em várias imagens. (Converter cores, trocar cores, etc).
mas este componente é um aplicativo externo, chamado através de uma DLL.
Quando tenho um arquivo gravado no disco, consigo executar normalmente o programa e gravar os dados no arquivo, mas o que quero fazer é passar a imagem diretamente da memória, armazenada em um TBitmap para o programa.

Quando trabalhando com memória, o programa exige que se passe o handle do bitmap, mas quando eu passo o bitmap.handle ele me informa que falou ao duplicar o Handle da imagem. O desenvolvedor me informou que a única maneira de enviar este handle seria enviando o handle de um memory mapped file.

Como faço para transformar o meu bitmap para memory mapped file.
Alguem tem alguma idéia?

Muito obrigado.


Prgdelphi

Prgdelphi

Curtidas 0

Respostas

Siam

Siam

03/10/2005

Vc pode passar esse Bitmap por SendMessage c/ msg=WM_CopyData


GOSTEI 0
Prgdelphi

Prgdelphi

03/10/2005

Fiz uma pesquisa na net e aqui está um exemplo de como estou tentando fazer..
Pelo que li nas páginas, aparentemente quando você passa o bitmap pra um Memory-mapped file, o bmp perde a informação de resolução X e Y. É correto isso?


procedure BitmapToMMF(bmp : Tbitmap);
var hMapObj  : THandle;    // mapped file handle
    PMapView : PLongInt;   // memory region
    Stream : TmemoryStream;
begin

  hMapObj := CreateFileMapping(
             $FFFFFFFF,                  // not a disk file
             Nil,                        // attributes
             PAGE_READWRITE,             // read and write
             0,                          //
             SizeOf(DWORD),              // size
             ´shared_memory´);           // "name"
  if hMapObj = 0 Then
  begin
    ShowMessage(´MapFileError´);
    // Error, exit
  end;

  Stream := TMemoryStream.Create;
  bmp.SaveToStream(Stream);

  GetMem(PMapView,Stream.Size); // allocate memory
  //
  // Get address of the region
  //
  PMapView := (MapViewOfFile(hMapObj, FILE_MAP_WRITE, 0, 0, 0));
  stream.Position := 0;
  stream.Read(PMapView,stream.Size);
  //PMapView^ := 1 SHL 8 + 2; //Exemplo jogando valores para o mmf

  UnmapViewOfFile(PMapView);             // free memory
  CloseHandle(hMapObj);                  // close "file"
  FreeAndNil(Stream);
end


Este é apenas um procedimento de teste. Não está funcionando. Alguém tem alguma dica?

Siam, você disse que posso passar através do SendMessage, poderia me dar um exemplo?

Muito obrigado.[/code]


GOSTEI 0
Siam

Siam

03/10/2005

O lado que manda:
var CDS:CopyDataStruct; MS:TMemoryStream;
begin
  MS := TMemoryStream.Create;
  Bitmap.SaveToStream(MS);
  CDS.dwData := 0;
  CDS.cbData := MS.Size;
  CDS.lpData := MS.Memory;
  SendMessage(Handle_do_Destino, WM_CopyData, 0, lParam(@CDS));
  MS.Free;
O lado que recebe:
var pCDS:pCopyDataStruct; MS:TMemoryStream;
begin
  MS     := TMemoryStream.Create;
  pCDS := pCopyDataStruct(Msg.LParam);
  MS.SetSize(pCDS^.cbData);
  Move(pCDS^.lpData^, MS.Memory^, MS.Size);
  Bitmap.LoadFromStream(MS);
  MS.Free;



GOSTEI 0
Siam

Siam

03/10/2005

Esquecí de mencionar, do lado que recebe declare a procedure:
    procedure Recebendo_Bitmap(var Msg:TMessage); message WM_COPYDATA;
e coloque o código na sua implementação.


GOSTEI 0
Prgdelphi

Prgdelphi

03/10/2005

Obrigado pelo exemplo siam, mas não funcionou aqui pois a DLL exige que seja passado o handle de um arquivo mapeado na memória.

Fiz da seguinte maneira e aparentemente funcionou:

procedure BitmapToMMF(bmp : Tbitmap);
var hMapObj  : THandle;    // mapped file handle
    PMapView : Pointer;   // memory region
    Stream : TmemoryStream;
begin
  Stream := TMemoryStream.Create;
  bmp.SaveToStream(Stream);

  hMapObj := CreateFileMapping(
             $FFFFFFFF,                  // not a disk file
             Nil,                        // attributes
             PAGE_READWRITE,             // read and write
             0,                          //
             stream.size,              // size
             ´shared_memory´);           // "name"
  if hMapObj = 0 Then
  begin
    ShowMessage(´MapFileError´);
    // Error, exit
  end;
  PMapView := (MapViewOfFile(hMapObj, FILE_MAP_WRITE, 0, 0, stream.size));
  stream.Position := 0;
  stream.Read(PMapView,stream.Size);
  UnmapViewOfFile(PMapView);             // free memory
  CloseHandle(hMapObj);                  // close "file"
  FreeAndNil(Stream);
end;


A dll recebeu a imagem, mas ainda me retornou que devo passar no formado DIB.
Alguém tem alguma idéia de como transformo o bitmap para DIB e gravar na stream para fazer este procedimento?

Obrigado pela ajuda.


GOSTEI 0
Siam

Siam

03/10/2005

Pensei que vc tivesse acesso aos fontes da dll.
Nunca criei bitmaps DI, mas dê uma olhada na função CreateDIBSection


GOSTEI 0
POSTAR