Fórum BMP -gt; String || String -gt; BMP #298969

10/10/2005

0

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

Responder

Posts

10/10/2005

Ipc$

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


Responder

Gostei + 0

11/10/2005

Rodc

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


Responder

Gostei + 0

11/10/2005

Ipc$

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.


Responder

Gostei + 0

13/10/2005

Rodc

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


Responder

Gostei + 0

13/10/2005

Ipc$

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.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar