Ir para conteúdo
Fórum Script Brasil
  • 0

Dimensões De Um Arquivo De Imagem


Paulo Nobre

Pergunta

Estou precisando obter as dimensões de um arquivo de imagem(bmp e jpg).

Por exemplo supondo que meu arquivo se chama Carro.jpg e que suas dimensões são 128x200, como obter, via código, o 128 e o 200?

Alguém sabe?

PS: Pesquisando o que encontro é a função GetImageSize, que é usada em PHP. Se servisse para delphi,

seria perfeita. Na ajuda do delphi, não sei se procurei direito, não encontrei nada.

Link para o comentário
Compartilhar em outros sites

16 respostass a esta questão

Posts Recomendados

  • 0

Eu não conheço nenhuma função que faça isso.

você pode fazer um TJPEG.LoadFromFile e ler as propriedades Width e Height para saber. Ou então conhecer a estrutura interna dos arquivos JPEG. Nas imagem Bitmap existem 2 registros de 4 bytes cada um no cabeçalho da imagem que informam a resolução horizontal e vertical. Só que como o formato do Bitmap varia também, a posição desses registros dentro do arquivo também varia. Então novamente é necessário conhecer a estrutura interna dos dados.

Link para o comentário
Compartilhar em outros sites

  • 0

var altura, largura : integer;

begin

  with TJPEGImage.Create do 
  begin 
    LoadFromFile('K:\Mulheres\Ellen Rocche01.jpg');
    altura:=height;
    largura:=width;
    free;
  end;
end;

Depois desse código as variaveis altura e largura conterão as dimensões em pixels do arquivo 'Ellen Rocche01.jpg'.

não seria necessário carregar a imagem na memória pra saber as dimensões se agente conhecesse a estrutura interna do arquivo.

Link para o comentário
Compartilhar em outros sites

  • 0

Vou tentar usar, obrigado Thales.

Uma pergunta: Para um bitmap seria análogo, ou seja, bastaria fazer

with bitmap.Create do

...??

PS:Se alguém conhecer alguma função da API do windows, que faça isto, e puder colocar aqui seria bom.

Link para o comentário
Compartilhar em outros sites

  • 0

Com o Bitmap seria a mesma coisa só que com TBitmap.create ao invés de TJPEGImage.create. Lembre-se de adicionar JPEG em uses. Talvez algum outro colega saiba de uma maneira melhor e possa ajudar.

Um abraço. Depois me manda esse programa aí.

Link para o comentário
Compartilhar em outros sites

  • 0

Valeu Thales vou testar suas sugestões.

Estou querendo este código, para testar o tamanho do papel de parede e caso seja menor do que um determinado valor, por exemplo, 300x300, ele já coloque em forma de ladrilho.

Tinha pensado como alternativa, antes de você postar, colocar um image invisível e ao mesmo tempo, que fosse escolhido o papel, o image receberia ele e com auto size = true conseguiria captar as dimensões do paepl pelo do image. Deu certo mais achei meio gambiarra.

Porisso achei que existiria uma função da API, para ficar mais elegante.

Um abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Rapá, de qualquel forma você vai ter que carregar a imagem na memória pra gerar o Bitmap, então você lê o Width e o Height direto da sua variável. Olhe, considere o seguinte ->

Vamos supor que você carregou um um JPEG numa var. ->

var jpg : TJPEGImage;
begin
  jpg:=TJPEGImage.Create;
  jpg.LoadFromFile('k:\mulheres\Daniella Cicarelli045.jpg');
end;
agora você passa ela pra um bitmap ->
var bmp : TBitmap;
begin
  bmp:=TBitmap.create;
  bmp.Assign(jpg);
end;
Aí você lê as propriedades width e height do Bitmap e descobre que as dimensões são 200 x 300. e você sabe que a resolução da tela é 800 x 600 por exemplo. então você vai ter que redimensionar a imagem para que ela ocupe a tela toda mantendo a proporção. - >
var
  aux : TBitmap;
  ih, iv, th, tv : integer; //ih = resolução horizontal da imagem, //th = resolução horizontal da tela
  sr, dr : TRect;
begin
  ih:=bmp.width;
  iv:=bmp.height;
  th:=800;//Aqui você coloca uma função que retorne a resolução horizontal da tela.
  tv:=600;//Aqui você coloca uma função que retorne a resolução vertical da tela.
  aux:=TBitmap.Create;
  
  sr.top:=0; sr.left:=0; 
  sr.right:=ih; sr.bottom:=iv;// sr é o retangulo de fonte.

  dr.top:=0; dr.left:=0;

  if ((ih >= iv) and (th >= tv)) then
  begin
    dr.right:=th; 
    dr.bottom:=round((tv/iv)*tv);
  
  end;
  
  if ((iv >= ih) and (tv >= th)) then
  begin
    dr.right:=round((th/ih)*th); 
    dr.bottom:=tv;

  end;

  if ((iv >= ih) and (th >= tv)) then
  begin
    dr.right:=round(ih*(th/ih)); 
    dr.bottom:=tv;
    
  end;

  if ((ih >= iv) and (tv >= th)) then
  begin
    dr.bottom:=round(iv*(tv/iv)); 
    dr.right:=th;
   
  end;
  aux.width:=dr.right; aux.height:=dr.bottom;
  aux.canvas.copyrect(dr,bmp.canvas,sr);  
end;

eu acho que depois desse código o Bitmap aux conterá a imagem corretamente redimensionada para preencher a tela sem perder o aspecto. Eu acho, né, pode ter algum erro. Testa aí e faz um debug.

Link para o comentário
Compartilhar em outros sites

  • 0

Existem também uma função na Api Oleaut32:

uses Activex;
function OleLoadPicturePath(szURLorPath: POleStr; unkCaller: IUnknown;
  dwReserved: Longint; clrReserved: TOleColor; const iid: TIID;
  ppvRet: Pointer): HResult; stdcall; external 'oleaut32.dll';

var Pic:IPicture; Pix,PiY,PixelsX,PixelsY:Integer; H:HDC;
const IID_IPicture: TGUID = (D1:$7BF80980;D2:$BF32;D3:$101A;D4:($8B,$BB,$00,$AA,$00,$30,$0C,$AB));
begin
  H   := CreateCompatibleDC(0);
  PiX := GetDeviceCaps(H, LOGPIXELSX);
  PiY := GetDeviceCaps(H, LOGPIXELSY);
  ReleaseDC(Handle, H);
  OleLoadPicturePath('Caminho e nome da img', nil, 0, 0, IID_IPicture, @Pic);
  Pic.get_Width(PixelsX);
  Pic.get_Height(PixelsY);
  PixelsX := Round(PixelsX * Pix / 2540);
  PixelsY := Round(PixelsY * PiY / 2540);
end;

Link para o comentário
Compartilhar em outros sites

  • 0

ôpa agora a coisa esquentou e ficou boa. Tenho material para me divertir por um bom tempo, com as últimas dicas do Thales e do s3c.

Thales,

Usei TPicture ao invés de TBitmap e TJPEGImage, pois desta forma contemplo as duas.

Por enqaunto não deu erro. Será que poderrei vir a ter erros em algum momento?

O último código vou guardar para uma outra fase é muito mais que esperava. No momento estou escrevendo a parte que se for menor que 300x300 vai colocar em forma de ladrilho.

Na outra parte onde i usuário escolhe aí entrará mais sofisticação.

s3c,

Parece que é esta a função que estavamos falando e precisando, não é?

Agora me diga uma coisa:

Como uso:

PixelsX := Round(PixelsX * Pix / 2540);

PixelsY := Round(PixelsY * PiY / 2540);

Muito obrigado

Link para o comentário
Compartilhar em outros sites

  • 0

s3c,

Realmente quando cheguei em casa e testei vi que realmente era o que você falou.

Porém, estou com um problema com esta função.

Para testar usei c:\teste.jpg e deu certo.

Porém, não sei como faço para usar com um caminho vindo de OpenPictureDialog1.filename.

Estou fazendo OleLoadPicturePath(OpenPictureDialog1.filename, nil, 0, 0, IID_IPicture, @Pic);

Dá erro de incompatibilidade TFileName e PWideCar.

Preciso que a análise seja feita apartir da escolha do usuário nesta caixa de dialogo.

Mesmo colocando Nome:String e Nome:=OpenPictureDialog1.filename;

aí a incompatibilidade passa a ser de string e PWideChar.

Como saiu desta?

Link para o comentário
Compartilhar em outros sites

  • 0

Paulo, aquele código que eu postei está errado. Eu testei ele aqui e corrigi. Eu tranformei numa função que pega um arquivo jpg e salva em um arquivo bmp redimensionado para o tamanho da tela sem perder a proporção. ->

procedure ResizeToFit(sFile, dFile : String);
var
  aux, bmp : TBitmap;
  ih, iv, th, tv : integer; //ih = resolução horizontal da imagem, //th = resolução horizontal da tela
  sr, dr : TRect;
  jpg : TJPEGImage;
  ph, pv : real;
begin
  bmp:=tbitmap.Create;
  jpg:=TJPEGIMAGE.Create;
  jpg.LoadFromFile(sFile);
  bmp.Assign(jpg);
  jpg.Free;

  ih:=bmp.width;
  iv:=bmp.height;
  th:=GetSystemMetrics(SM_CXSCREEN);
  tv:=GetSystemMetrics(SM_CYSCREEN);
  aux:=TBitmap.Create;

  ph:=(ih/iv);
  pv:=(iv/ih);

  sr.top:=0; sr.left:=0;
  sr.right:=ih; sr.bottom:=iv;// sr é o retangulo de fonte.

  dr.top:=0; dr.left:=0;

  if ((ih >= iv) and (th >= tv)) then
  begin
    dr.right:=th;
    dr.bottom:=round(th*pv);

  end;

  if ((iv >= ih) and (tv >= th)) then
  begin
    dr.right:=round(tv*ph);
    dr.bottom:=tv;

  end;

  if ((iv >= ih) and (th >= tv)) then
  begin
    dr.right:=round(tv*ph);
    dr.bottom:=tv;

  end;

  if ((ih >= iv) and (tv >= th)) then
  begin
    dr.bottom:=round(th*pv);
    dr.right:=th;

  end;
  aux.width:=dr.right; aux.height:=dr.bottom;
  aux.canvas.copyrect(dr,bmp.canvas,sr);
  aux.SaveToFile(dFile);
  aux.Free;
  bmp.Free;
end;

então ResizeToFit('k:\mulheres\Keyra001.jpg','k:\keyraResized.bmp'); salva a imagem 'k:\mulheres\Keyra001.jpg' no arquivo 'k:\keyraResized.bmp' já redimensionada. Infelizmente o uso desse código não é encorajado porque deixa a qualidade da foto muito ruim. porque é o chamado redimensionamento Nearest Neighbor. Faça a prova aí.

Link para o comentário
Compartilhar em outros sites

  • 0

Acho que fazendo Pointer(String) não deverá funcionar porque o parâmetro requer um PWideChar(2 bytes p/ cada caracter) e não um PChar. Acho melhor converter:

  var p:PWideChar;
  p := AllocMem(Length(OpenPictureDialog1.filename) * 2 + 2);
  OleLoadPicturePath(StringToWideChar(OpenPictureDialog1.filename, p, Length(OpenPictureDialog1.filename) + 1), nil, 0, 0, IID_IPicture, @Pic);
  .
  .
  .
  FreeMem(p);

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...