BMP -gt; String || String -gt; BMP

Delphi

10/10/2005

Olá amigos,

Preciso converter uma imagem para String e depois converter a string para imagem novamente. Alguém pode me ajudar?

Grato,

Rodrigo Cesar


Rodc

Rodc

Curtidas 0

Respostas

Ipc$

Ipc$

10/10/2005

Vc pode salvar o bmp numa TStream e depois passar p/ String. Para retornar, vc faz o inverso.


GOSTEI 0
Rodc

Rodc

10/10/2005

É isto que eu estou tentando fazer, mas não estou conseguindo. Tem como postar um código de exemplo?


GOSTEI 0
Ipc$

Ipc$

10/10/2005

Salvar:
var MS:TMemoryStream;
begin
  MS := TMemoryStream.Create;
  try
    Bitmap.SaveToStream(MS);
    SetLength(sBmp, MS.Size);
    Move(MS.Memory^, sBmp[1], MS.Size);
  finally
    MS.Free;
  end;
end;

Voltar:
var MS:TMemoryStream;
begin
  MS := TMemoryStream.Create;
  try
    MS.SetSize(Length(sBmp));
    Move(sBmp[1], MS.Memory^, Length(sBmp));
    Bitmap.LoadFromStream(MS);
  finally
    MS.Free;
  end;
end;
sBmp é a string.


GOSTEI 0
Rodc

Rodc

10/10/2005

Valeu pela ajuda IPC, mas não pude usar seu exemplo, pois esta string deve ser passada por parâmetro por várias funções, não tem como eu ir dando SetSize em todas as Strings.
Resolvi passando o valor RGB de cada pixel para a string, ou seja, só é possível passar arquivo BMP. A string fica menor que enviar Stream de um arquivo de BMP, pois no arquivo tem o cabeçalho.
O código que fiz está em C++ (BCB), mas não poderia de deixar de postar aqui para caso alguém precise poder analisar.
O único problema é que não se pode colocar #0 na string, se não ele pensa que é o fim do texto, tentão eu troco todo 0 por 1 que seria um preto um pouco mais claro, mas não vai fazer diferença na imagem.
Outro problema é que o segundo bitmap tem que ser feito um LoadFromFile ou Assign de um outro bitmap válido, se não ele não funciona.

    AnsiString sImagem;
    if (OpenDialog->Execute())
    {
        // Carrega imagem a ser transferida
        Image1->Picture->Bitmap->LoadFromFile(OpenDialog->FileName);
        Graphics::TBitmap *pBitmap = new Graphics::TBitmap();
        Graphics::TBitmap *pBitmap2 = new Graphics::TBitmap();
        Byte *ptr, *ptr2;

        pBitmap->Assign(Image1->Picture->Bitmap);

        OpenDialog->Execute();
        // Carrega qualquer imagem para preencher o TImage de destino
        pBitmap2->LoadFromFile(OpenDialog->FileName);
        // Ajusta o tamanho da segunda imagem conforme a primeira
        pBitmap2->Height = pBitmap->Height;
        pBitmap2->Width  = pBitmap->Width;

        for (int y = 0; y < pBitmap->Height; y++)
        {
          ptr = (Byte *)pBitmap->ScanLine[y];
          for (int x = 0; x < pBitmap->Width*3; x++)
          {
            if (ptr[x] == 0)
                sImagem += (char)1;  //para não corromper a string
            else
                sImagem += (char)ptr[x];
          }
        }

        int count=0;
        char *str;
        str = sImagem.c_str();

        // Trasfere os pixes da string para a nova imagem
        for (int y = 0; y < pBitmap2->Height; y++)
        {
          ptr = (Byte *)pBitmap2->ScanLine[y];

          for (int x = 0; x < pBitmap2->Width*3; x++, count++)
          {
            Byte valor = (Byte)str[count];
            ptr[x] = valor;
          }
        }
        Image2->Picture->Bitmap->Assign(pBitmap2);
    }


Abraços,

Rodrigo Cesar


GOSTEI 0
Ipc$

Ipc$

10/10/2005

A questão de passar somente o RGB, concordo que irá ficar menor.
Quanto ao SetSize, ele é dado na TStream e não na string.
Quanto ao #0 em strings, não interfere desde que vc a utilize em memória; para passá-la como parâmetro, vc pode utilizar um PChar pq um SetLength na string garante a memória alocada e os bytes contínuos naquele espaço dentro do escopo local ou global.


GOSTEI 0
POSTAR