O relacionamento de herança de TMemoryStream é o seguinte
TObject
|
Stream
|
TCustomMemoryStream
|
TMemoryStream
Como usar o TMemoryStream?
Na verdade, TmemoryStream é usado exatamente como TStream.
Para atributos e métodos específicos, consulte a ajuda.
Aqui está um exemplo:
O que devo fazer se quiser ler e escrever um Bitmap diretamente na memória?
TmemoryStream te ajuda muito
var
BitmapMemoryStream:TMemoryStream;
Bitmap1:TBitmap;
Procedimento TForm.Button1Click(Sender:TObject);
começar
BitmapmemroyStream:=TmemoryStream.Create arquivo://Criar MemoryStream
Bitmap1:=TBitmap.Create;
tentar
Bitmap1.LoadFromFile('d:Bitmap1.bmp');
exceto
ShowMessage('Erro ao carregar arquivo bitmap1.bmp');
fim;
fim;
procedimento TForm.Button2Click(Sneder:Tobject);
começar
se atribuído (Bitmap1) então
Bitmap1.SaveToStream(BitmapmemoryStream);
fim;
procedimento TForm.Button3Click(Sender:TObject);
começar
se BitmapMemoryStream<>nil então
começar
tentar
BitmapMemroyStream.SaveToFile('Bitmap1.str'); arquivo://fluxo de memória salvo, tamanho e
arquivo://Bitmap1.bmp mesmo
exceto
showmessage('erro na memória de acesso!');
fim;
fim;
fim;
procedimento TForm.Button4Click(Sender:TObject);
var
Buffer:Array[0..53] de char;
começar
se atribuído (BitmapMemroyStream) então
tentar
BitmapMemroyStream.Seek(0,soFromBeginning);
BitmapMemoryStream.Read(Buffer,54);
se Buffer[0]='B' e Buffer[1]='M' então file://reescrever o conteúdo da memória
começar
BitmapMemoryStream.Seek(0,soFromBeginning);
BitmapmemoryStream.Write('ICE',3);
Button3Click(Sender); //Escreve o conteúdo reescrito no arquivo
fim;
exceto
ShowMessage('erro ao acessar memroyStream');
fim;
fim;
Você pode ver como é conveniente usar TMemoryStream para ler e gravar memória. Claro, não há necessidade de construir um Bitmap primeiro.
Você pode usar LoadFromFile para inicializar diretamente o arquivo, mas para outros fluxos de memória, você pode usar o método acima.
O texto acima é apenas uma introdução. Para outras funções, você pode ler a ajuda e descobrir por si mesmo!
Existem muitos outros objetos de streaming, todos praticamente iguais, então você pode usar todos eles!
Como gravar o conteúdo de um stream na área de transferência e processar
Esta técnica é realizada com referência à implementação da classe clipboard do Delphi. Coloque o conteúdo de um stream na área de transferência,
Primeiro, registre seu próprio formato usando a função RegisterClipboardFormat()
Em seguida, execute as três etapas a seguir:
1. Crie um fluxo de conteúdo e escreva o conteúdo nele
2. Crie uma área de conteúdo global e escreva o conteúdo do stream
3. Chame ClipBoard.SetAsHandle() para gravar o conteúdo na área de transferência
Escreva conteúdo na área de transferência
var
hbuf :THandle;
bufptr: Ponteiro;
mstream: TMemoryStream;
começar
mstream := TMemoryStream.Create;
tentar
{-- Código para processamento de fluxos --}
hbuf := GlobalAlloc(GMEM_MOVEABLE, mstream.size);
tentar
bufptr := GlobalLock(hbuf);
tentar
Mover(mstream.Memory^, bufptr^, mstream.size);
Clipboard.SetAsHandle(CF_MYFORMAT, hbuf);
finalmente
GlobalUnlock(hbuf);
fim;
exceto
GlobalFree(hbuf);
elevação;
fim;
finalmente
mstream.Free;
fim;
fim;
Tenha cuidado para não liberar o buffer global alocado. Este trabalho é feito pela área de transferência ao ler os dados.
Você deve copiá-lo e processá-lo mais tarde.
Leia o conteúdo da área de transferência
var
hbuf :THandle;
bufptr: Ponteiro;
mstream: TMemoryStream;
começar
hbuf := Área de Transferência.GetAsHandle(CF_MYFORMAT);
se hbuf <> 0 então comece
bufptr := GlobalLock(hbuf);
se bufptr <> nulo então comece
tentar
mstream := TMemoryStream.Create;
tentar
mstream.WriteBuffer(bufptr^, GlobalSize(hbuf));
mstream.Position := 0;
{-- Código para processamento de fluxos --}
finalmente
mstream.Free;
fim;
finalmente
GlobalUnlock(hbuf);
fim;
fim;
fim;
fim;
Dicas para usar TStream para ler e gravar dados em Dephi
Um tipo de dados abstrato TStream é fornecido no Dephi para suportar operações em streaming de dados. Esses dados geralmente vêm de arquivos, bancos de dados, objetos de memória, objetos OLE, etc. TStream fornece um método unificado e conciso para ler e gravar dados. Em circunstâncias normais, não precisamos usar a classe TStream diretamente, e a leitura e gravação de dados de streaming são encapsuladas nos métodos de controle VCL. Mas se esses métodos não atenderem aos nossos requisitos, precisaremos controlar manualmente a leitura e a gravação dos dados.
1. Métodos e propriedades comumente usados do TStream:
---- 1. função Read(var Buffer; Contagem: Longint): Longint virtual;
---- 2. função Write(const Buffer; Contagem: Longint): Longint virtual;
---- 3. função Seek(Offset: Longint; Origem: Word): Longint virtual;
---- 4. Posição da propriedade: Longint;
---- 5. Tamanho da propriedade: Longint
---- Ler, escrever e procurar são funções virtuais puras, fornecendo métodos abstratos para leitura, gravação e posicionamento de dados. O método Read lê os dados do Stream para o Buffer, e o método Write implementa a operação oposta. O valor de retorno indica o tamanho real dos dados lidos e gravados. Seek fornece um método para mover o ponteiro de dados no Stream. O parâmetro Origin pode assumir três valores: soFromBeginning, soFromCurrent e soFromEnd é o deslocamento e o valor de retorno é a posição do ponteiro de dados do Stream atual.
---- Posição representa a posição do ponteiro de dados no Stream. Esta propriedade é legível e gravável. Na verdade, é implementada chamando o método Seek, portanto, é mais conveniente usar essa propriedade no uso real. O atributo Size indica o tamanho do Stream atual. Para diferentes Streams, às vezes é somente leitura.
2. Leitura e gravação de dados de Stream.
---- 1. SaveToStream(Stream: TStream); file://grava os dados da classe na posição atual do Stream
---- 2. LoadFromStream(Stream: TStream); file://Leia os dados em Stream da posição atual
---- No uso real, basicamente precisamos usar apenas as duas funções acima.
3. Exemplos
----O diagrama de árvore de herança do TStream é mostrado na Figura 1 (omitido). No uso real, TFileStream, TMemoryStream e TblobStream são mais comumente usados.
---- Crie um formulário Form1, coloque três botões btnRead, btnInvert, btnSave e uma caixa de diálogo de abertura de arquivo OpenDialog1 bem como controles de dados DataSource1, Table1, test.
---- Use o Database Desktop fornecido pelo Dephi para criar um teste de tabela. Há um campo Imagem na tabela e o nome do arquivo do banco de dados é salvo como test.db. Coloque um controle TDatabase dbTest, um controle TTable Table1, um controle DataSource DataSource1 e um controle TDBNavigator DBNavigator1 no formulário. Conecte dbTest ao banco de dados recém-criado pelo Desktop, defina a propriedade TableName de Table1 como test.db, defina a propriedade DataSet de DataSource1 como Table1, defina a propriedade DataSource de DBNavigator1 como DataSource1 e defina as primeiras quatro propriedades VisibleButtons como TRUE. Além disso, configure Connected do dbtest como TRUE e a propriedade Active da Table1 como TRUE para que o banco de dados fique aberto desde o início.
----O código do evento é escrito da seguinte forma:
---- 1. Clique no evento btnRead, aqui demonstra o uso do TFileStream.
var
MS: TFileStream;
começar
se OpenDialog1.Execute então
começar
MS:=TFileStream.Create
(OpenDialog1.FileName,fmOpenRead);
Imagem1.Picture.Bitmap.LoadFromStream(MS);
MS.Livre;
fim;
fim;
---- 2. Clique no evento btnInvert, aqui demonstra o uso de TMemoryStream. É utilizada a função Invert, que é uma função simples que inverte a cor de uma imagem (válida apenas para imagens true color). Ela retorna um ponteiro para o bloco de dados da imagem processada.
var
M
S:TMemoryStream;
pImagem: ponteiro;
começar
MS:=TMemoryStream.create;
Imagem1.Picture.Bitmap.SaveToStream(MS);
MS.Posição:=0;
pImagem:=Inverter(MS.Memória, MS.tamanho);
O atributo file://Memory é um ponteiro para o bloco de memória real
MS.Write(pImage^,MS.tamanho);
MS.Posição:=0;
A linha de código anterior em file:// move o ponteiro para o final do Stream, portanto, ele precisa ser redefinido.
Imagem1.Picture.Bitmap.LoadFromStream(MS);
FreeMem(pImagem);
MS.Livre;
fim;
A função Inverter é a seguinte:
função TForm1.Invert
(pImagem: ponteiro; tamanho: Inteiro): ponteiro;
var
pData, pMem: PChar;
eu: inteiro;
começar
pMem:=AllocMem(tamanho);
CopyMemory(pMem,pImagem,tamanho);
pDados:=pMem+54;
para i:=0 até tamanho-54-1 faça
começar
pData^:=Char(não inteiro(pData^));
pDados:=pDados+1;
fim;
Resultado:=pMem;
fim;
---- 1. Evento Click de btnSave, aqui demonstra outro uso do TMemoryStream, gravando os dados do Stream no banco de dados.
var
MS: TMemoryStream;
começar
MS:=TMemoryStream.create;
Imagem1.Picture.Bitmap.SaveToStream(MS);
MS.Posição:=0;
Tabela1.Anexar;
file://adiciona um registro no banco de dados
TBlobField(Tabela1.CampoporNome
('imagem')).LoadFromStream(MS);
Tabela1.Postagem;
file://grava as atualizações no banco de dados
fim;
---- 4. Evento Click do DBNavigator1, aqui demonstra a utilização do TBlobStream, utilizando um método diferente da escrita para leitura dos dados de imagem do banco de dados.
var
MS: TStream;
começar
com Tabela1 faça
MS:=CriarBlobStream
(FieldbyName('imagem'),bmRead);
Imagem1.Imagem.Bitmap.
CarregarFromStream(MS);
MS.Livre;
fim;
É isso. Obrigado por ler este artigo. Não tenho pontos suficientes para usar, então preciso ganhar alguns pontos para resgatá-los. Se você acha que este artigo é útil para você, vote em mim, obrigado.