TMemoryStream: Resolva o problema para imagens grandes
Essa dica vai ajudar muita gente!
Já aconteceu com você de precisar transferir uma imagem (principalmente JPEG) ou qualquer outro Stream (seja via datasnap ou qualquer outro meio) e se deparar com vários erros gerados pelo Delphi? Um deles é o "Out of memory while expanding..."
Acontece que o TMemoryStream só aceita até 40kb, segundo o docwiki da embarcadero e isso é um problema sério pra nós programadores.
Mas vamos lá, sem mais, declare a função abaixo no seu código e quando for salvar ou carregar seu Stream, use-a. Vou dar exemplos abaixo.
Para usar:
Já aconteceu com você de precisar transferir uma imagem (principalmente JPEG) ou qualquer outro Stream (seja via datasnap ou qualquer outro meio) e se deparar com vários erros gerados pelo Delphi? Um deles é o "Out of memory while expanding..."
Acontece que o TMemoryStream só aceita até 40kb, segundo o docwiki da embarcadero e isso é um problema sério pra nós programadores.
Mas vamos lá, sem mais, declare a função abaixo no seu código e quando for salvar ou carregar seu Stream, use-a. Vou dar exemplos abaixo.
function CopyStream( const source: TStream ): TStream;
//resolve o problema de memory stream com mais de 40kb
var
BytesRead: Integer;
Buffer: PByte;
const
MaxBufSize = $F000;
begin
{ ** Criando a instância do objeto TMemoryStream para retorno do método ** }
result := TMemoryStream.Create;
{ ** Reposicionando o stream para o seu início ** }
source.Seek( 0, TSeekOrigin.soBeginning );
source.Position := 0;
GetMem( Buffer, MaxBufSize );
{ ** Realizando a leitura do stream original, buffer a buffer ** }
repeat
BytesRead := Source.Read( Buffer^, MaxBufSize );
if BytesRead > 0 then
result.WriteBuffer( Buffer^, BytesRead );
until MaxBufSize > BytesRead;
{ ** Reposicionando o stream de retorno para o seu início ** }
result.Seek( 0, TSeekOrigin.soBeginning );
end;
Para usar:
TempStream:= TMemoryStream.Create; IMG.Graphic.SaveToStream(TempStream); Result:= CopyStream(TempStream);
- TempStream = TMemoryStream
- IMG = TPicture
- A função retorna um TStream
Quando for dar um loadfromstream, use a função também:
vFoto1.LoadFromStream(CopyStream(StreamRetorno))
Desse modo, você pode enviar Streams de qualquer tamanho!
Abraço a todos!
Muito obrigado pela dica. Acabei de usar em um projeto aqui no trabalho.
ResponderExcluirUm abraço!
boa noite.
ResponderExcluirestou tentando salvar as configurações de um cxgrid usando o comando...storedtostream(Stream);
em seguida pegar o conteudo da variavel Stream e atribuir num memo. no entanto. no memo só aparece o inicio...não aprece toda informação
ja usei a função acima, mas mesmo assim não da certo.
gvLog.StoreToStream(TempStream);
cxMemo1.lines.LoadFromStream(CopyStream(TempStream));
consegue me ajudar?
grato
Olá... vc deve usar a funcao copystream tanto no save quanto no load....
ExcluirEx: gvLog.StoreToStream(CopyStream(TempStream));
Estou utilizando Delphi 2010 + ClientDataSet + Oracle 11g.
ResponderExcluirTenho um clientdataset com um campo Blob para gravar fotos.
Antes quando eu utilizava o Delphi 7, eu usava da seguinte forma:
OpenPictureDialog1.FileName := '';
OpenPictureDialog1.InitialDir := '\\DADOS\LOGOMARCAS';
OpenPictureDialog1.Execute;
try
if OpenPictureDialog1.FileName > '' then
CdsEmpresaLOGO.LoadFromFile(OpenPictureDialog1.FileName)
else
CdsEmpresaLOGO.Clear;
except
CdsEmpresaLOGO.Clear;
dmConexao.msg.MessageBox('Não foi possível carregar a imagem!','ATENÇÃO',MB_OK+MB_ICONERROR);
end;
funcionava perfeitamente, agora com a mudança a partir da versão do Delphi 2010 para trabalhar com Unicode em campos Blob, esse procedimento acima não funciona mais.
Gostaria de saber se alguém sabe como resolver o problema, pois não encontrei nenhuma solução na Net.
Obrigado!
Estou utilizando Delphi 7
ResponderExcluirMesmo colocando o comando CopyStream no SaveToStream e no LoadFromStream não está funcionando.
procedure fundi_wptools(Origem, Destino: TWPcustomRichText);
var
StreamAux:TmemoryStream;
begin
StreamAux := TMemoryStream.Create;
try
Origem.SaveToStream(CopyStream(StreamAux));
StreamAux.Position := 0;
Destino.LoadFromStream(CopyStream(StreamAux));
finally
StreamAux.free;
end;
end;
Perfeito! Obrigado pela dica.
ResponderExcluir