Pergunta

Eu preciso exibir miniaturas de imagens em um determinado diretório. Eu uso TFileStream para ler o arquivo de imagem antes de carregar a imagem em um componente de imagem. O bitmap é então redimensionada para o tamanho da miniatura, e atribuído a um componente TImage em um TScrollBox.

Parece ok trabalho, mas retarda bastante com imagens maiores.

Existe uma maneira mais rápida de arquivos do disco de carregamento (imagem) e redimensionando-los?

Obrigado, Pieter

Foi útil?

Solução

Não é verdade. O que você pode fazer é redimensionar-los em uma discussão de fundo, e usar uma imagem de "espaço reservado" até o redimensionamento é feito. Eu, então, salvar essas imagens redimensionadas para algum tipo de arquivo de cache para processamento posterior (Windows faz isso, e chama o thumbs.db de cache no diretório atual).

Você tem várias opções sobre a própria arquitetura fio. Um único segmento que faz todas as imagens, ou um pool de threads, onde um fio só sabe como processar uma única imagem. A AsyncCalls biblioteca é ainda uma outra maneira e pode manter as coisas bastante simples.

Outras dicas

Eu vou complementar a resposta por skamradt com uma tentativa de projetar este por ser o mais rápido possível. Para isso, você deve

  • otimizar I / O
  • usar vários segmentos para fazer uso de múltiplos núcleos de CPU, e para manter até mesmo um único núcleo da CPU trabalhando enquanto você ler (ou escrever) arquivos

O uso de vários segmentos implica que usando classes VCL para o redimensionamento não está indo para o trabalho, como a VCL não é thread-safe, e todos os hacks em torno de que não escala bem. de efg Lab Computer tem ligações para o código de processamento de imagem.

É importante para não causar várias operações simultâneas de E / S ao usar vários segmentos. Se você optar por escrever a miniatura imagens voltar para arquivos, em seguida, uma vez que você começou a ler um arquivo que você deve lê-lo completamente, e depois de ter começado a escrever um arquivo que você também deve escrever-lo completamente. Intercalação ambas as operações vai matar o seu I / O, porque você potencialmente causar um monte de buscar operações da cabeça de disco rígido.

Para obter os melhores resultados a leitura (e escrita) de arquivos também não deve acontecer no principal (GUI) fio de sua aplicação. Isso sugeriria o seguinte projeto:

  • Tem um segmento ler arquivos em TGraphic objetos, e colocá-los em uma lista thread-safe.
  • Tenha uma espera pool de threads na lista de arquivos no tamanho original, e tem um processo de rosca um TGraphic objeto, redimensioná-la em outro objeto TGraphic, e adicione a outra lista thread-safe.
  • Notificar o segmento GUI para cada imagem em miniatura adicionado à lista, para que possa ser exibido.
  • Se miniaturas devem ser escritos para o arquivo, fazer isso no segmento de leitura, bem como (veja acima para uma explicação).

Editar:

Na re-ler o seu aviso pergunta que eu que você talvez só precisa redimensionar uma imagem, caso em que uma única discussão de fundo é claro o suficiente. Vou deixar a minha resposta no lugar de qualquer maneira, talvez ele vai ser de utilidade para alguém algum tempo. É o que eu aprendi com um dos meus projetos mais recentes, onde o programa final poderia ter precisava de um pouco mais de velocidade, mas apenas estava usando cerca de 75% da máquina quad core nos horários de pico. Dissociação I / O de processamento teria feito a diferença.

Costumo usar TJPEGImage com Escala: = jsEighth (em Delphi 7). Isso é muito rápido porque o JPEG de compressão pode pular um monte de dados para preencher um bitmap de apenas um oitavo de largura e altura.

Outra opção é usar o método de shell para extrair uma miniatura , que bonito é rápido bem

Eu estou no negócio de visão, e eu simplesmente enviar as imagens para a GPU usando OpenGL. (Tipicamente 20x 2048x2000x8bpp por segundo), um bmp per textura, e deixe a escala de vídeo (win32, cabeçalhos OpenGL de Mike Lischke)

Fazer upload de tal custos imagem 5-10ms dependendo videocard exata (se não integrado e nvidia série 7300 ou mais recente. Muito recentes GPUs integradas pode ser factível também). Dimensionamento e exibição de custos 300US. O que significa que os clientes podem deslocar e ampliar como um louco, sem tocar no aplicativo. Eu desenhar uma sobreposição (que costumava ser um TMetafile, mas agora é um formato próprio) em cima dela.

Meu maior imagem é 4096x7000x8bpp que shows e escalas em menos de 30ms. (GF 8600)

Uma limitação desta tecnologia é o tamanho máximo de textura. Ele pode ser resolvido por fragmentar a imagem em várias texturas, mas eu ainda não ter se incomodado porque eu entregar os sistemas com o software.

(alguns tamanhos típicos: série nv6x00: 2k * 2k mas upload é apenas sobre break even em comparação com GDI série nv7x00: 4k * 4k Para mim, os cartões de linha de base. de GF7300 são como US $ 20-40 série nv8x00: 8k * 8k )

Note que este pode não ser para todos. Mas se você está na situação sorte para especificar limites de hardware, ele poderia funcionar. O principal problema são laptops como Thinkpads, as GPUs de que são mais velhos do que o laptop média, que são, por sua vez, muitas vezes uma geração atrás Desktops.

Eu escolhi OpenGL sobre DirectX porque é mais estática no tempo, e mais fácil de encontrar exemplos relacionados não-jogo.

Tente olhar para o Graphics32 biblioteca : é muito bom em desenho coisas e obras grande com bitmaps. Eles são Thread - seguro com bom exemplo, e é totalmente gratuito

.

Exploit janelas capacidade de criar miniaturas. Lembre-se que os arquivos Thumbs.db escondidos em pastas que contêm imagens?

Eu tenho implementado algo como esse recurso, mas em VB. Meu software é capaz de miniaturas construção de 100 arquivos (tamanho misto) em cerca de 10 segundos.

Eu não sou capaz de convertê-lo em Delphi embora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top