desde que você solicitou uma biblioteca, a resposta real está aqui: stackoverflow.com/questions/244164/… . É muito mais fácil de usar do que o código em resposta aceita;)
Artur Gajowy
Discordo da parte da biblioteca: O Graphics2D faz parte da biblioteca awt e é de código aberto. Para a última parte (código aberto), não tenho 100% de certeza, mas quem veria o código awt de qualquer maneira?
Eu descobri que essa técnica cria uma imagem que não é de qualidade suficiente para minhas necessidades.
morgancodes
1
Image.getScaledInstance (largura, altura, dicas) também funciona?
codeplay
1
o preserveAlpha verifica o caminho errado (para o imageType)?
Thilo
Eu concordo com @morgancodes. A qualidade da imagem é muito pior do que a que você obtém, por exemplo, OS X Preview ao redimensionar para as mesmas dimensões. Tentará algumas bibliotecas de código aberto para ver se elas se saem melhor.
Thilo
1
"Vou tentar algumas bibliotecas de código aberto para ver se elas se saem melhor." +1 para imgscalr da resposta de @ RiyadKalla.
Thilo
182
FWIW Acabei de lançar (Apache 2, hospedado no GitHub) uma biblioteca simples de dimensionamento de imagens para Java chamada imgscalr (disponível no Maven central ).
A biblioteca implementa algumas abordagens diferentes para o dimensionamento de imagens (incluindo a abordagem incremental de Chris Campbell com alguns aprimoramentos menores) e escolherá a melhor abordagem para você, se você pedir, ou fornecerá a aparência mais rápida ou bonita (se você peça isso).
O uso é simples, apenas um monte de métodos estáticos. O caso de uso mais simples é:
Todas as operações mantêm as proporções originais da imagem; portanto, neste caso, você está solicitando ao imgscalr que redimensione sua imagem dentro de limites de 200 pixels de largura e 200 pixels de altura e, por padrão, selecionará automaticamente a abordagem mais rápida e bonita para isso, pois não foi possível. não especificado.
Percebo desde o início que isso se parece com autopromoção (é), mas gastei minha parte justa do tempo pesquisando exatamente esse mesmo assunto e continuei apresentando diferentes resultados / abordagens / pensamentos / sugestões e decidi sentar e escrever uma implementação simples que abordaria os casos de uso de 80 a 85% em que você tem uma imagem e provavelmente deseja uma miniatura para ela - o mais rápido possível ou o mais bonito possível (para aqueles que tentaram, você notará fazendo uma Graphics.drawImage, mesmo com interpolação BICUBIC em uma imagem pequena o suficiente, ainda parece lixo).
Riyad, gostei de usar o Scalr. Estou curioso para saber, como você acabou escolhendo uma API com todos os métodos estáticos? Eu havia escrito uma API semelhante, mais próxima de um construtor. Like new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer(). Também gosto do seu jeito e acho que é mais simples.
Amir Raminfar
4
Amir, o padrão do construtor também funciona maravilhosamente para esses tipos de bibliotecas, por acaso eu segui a abordagem do método estático, porque achei que era um cabelo mais fácil de seguir para novos usuários e o padrão de uso que eu esperava do imgscalr (originalmente apenas métodos de redimensionamento único) não se beneficiaram de ter uma instância mantendo o estado (A instância do construtor). Então eu salvei na instanciação do objeto e fui com os métodos estáticos. Adotei uma forte posição contra a criação de objetos dentro do imgscalr em todos os lugares em que posso evitá-lo. Ambas as abordagens funcionam muito bem.
Riyad Kalla
5
+1 por disponibilizá-lo no repositório central do Maven!
Grilse 21/09/12
O que é essa classe BufferedImage, por que o estúdio android não a encontra? @Riyad Kalla
Milad
3
@ xe4me BufferedImage é uma classe no J2SE JDK (parte da estrutura Java2D) usada para representar dados de pixel brutos e não compactados. Ele não está disponível no Android, o Android fornece suas próprias classes para trabalhar com dados de imagem.
Riyad Kalla 23/03
54
Thumbnailator é uma biblioteca de redimensionamento de imagem de código aberto para Java com uma interface fluente, distribuída sob a licença MIT.
Eu escrevi esta biblioteca porque criar miniaturas de alta qualidade em Java pode ser surpreendentemente difícil e o código resultante pode ser bastante confuso. Com o Thumbnailator, é possível expressar tarefas bastante complicadas usando uma API fluente simples.
Um exemplo simples
Para um exemplo simples, é possível obter uma imagem e redimensioná-la para 100 x 100 (preservando a proporção da imagem original) e salvando-a em um arquivo em uma única declaração:
Uma observação sobre a qualidade e velocidade da imagem
Essa biblioteca também usa o método de dimensionamento bilinear progressivo destacado em Filthy Rich Clients por Chet Haase e Romain Guy, a fim de gerar miniaturas de alta qualidade e garantir um desempenho de tempo de execução aceitável.
O artigo de Chris é exatamente o que me motivou a escrever imgscalr em primeiro lugar; e perguntas como essa (e respostas como a sua). Muitas pessoas perguntam repetidamente como obter miniaturas com boa aparência de uma imagem. Existem várias maneiras de fazer isso, o Chris nem sempre é o melhor, depende do que você está tentando fazer e do tamanho da redução. O imgscalr aborda tudo isso e é uma classe.
Riyad Kalla
2
+1, eu concordo, o Filthy Rich clients é um dos melhores livros em Java, a par do "Effective java", mas o ImgScalr é o que eu uso porque sou preguiçoso.
Se você está lidando com imagens grandes ou deseja um resultado bonito, não é uma tarefa trivial em java. Simplesmente fazê-lo através de uma operação de revenda via Graphics2D não criará uma miniatura de alta qualidade. Você pode fazer isso usando JAI, mas requer mais trabalho do que você imagina para obter algo que pareça bom e a JAI tem o hábito desagradável de explodir nossa JVM com erros OutOfMemory.
Eu sugiro usar o ImageMagick como um executável externo, se você puder se safar. É simples de usar e faz o trabalho corretamente para que você não precise.
Se a opção imagemagick instalada no seu maschine for uma opção, eu recomendo o im4java . É uma camada de abstração muito fina na interface da linha de comando, mas faz seu trabalho muito bem.
Ele também está disponível no GitHub ( github.com/mortennobel/java-image-scaling.git ) e possui a versão 8.7 até o momento. Ele precisava ser corrigido no pom.xml, tu (alterando a origem e o destino para pelo menos 1,6, pois o Maven mais recente não suporta mais o 1.5).
Image Magick foi mencionado. Existe um projeto de front end da JNI chamado JMagick. Não é um projeto particularmente estável (e se sabe que o Image Magick muda muito e até quebra a compatibilidade). Dito isso, tivemos uma boa experiência usando o JMagick e uma versão compatível do Image Magick em um ambiente de produção para executar o dimensionamento com alta taxa de transferência e baixa latência. A velocidade foi substancialmente melhor do que com uma biblioteca de gráficos Java que tentamos anteriormente.
Você também pode definir o valor como BICUBIC, ele produzirá uma imagem de melhor qualidade, mas é uma operação mais cara. Existem outras dicas de renderização que você pode definir, mas eu descobri que a interpolação produz o efeito mais notável. Lembre-se de que, se você quiser aumentar bastante o zoom, o código java provavelmente será muito lento. Acho que imagens maiores começam a produzir lag em torno de 300% de zoom, mesmo com todas as dicas de renderização definidas para otimizar a velocidade sobre a qualidade.
Acontece que escrever um scaler de desempenho não é trivial. Eu fiz isso uma vez para um projeto de código aberto: ImageScaler .
Em princípio, 'java.awt.Image # getScaledInstance (int, int, int)' também faria o trabalho, mas há um bug desagradável com isso - consulte meu link para obter detalhes.
Eu desenvolvi uma solução com as classes disponíveis gratuitamente (AnimatedGifEncoder, GifDecoder e LWZEncoder) disponíveis para lidar com animação GIF.
Você pode fazer o download do jar jgifcode e executar a classe GifImageUtil. Link: http://www.jgifcode.com
Se você não deseja importar o imgScalr como a resposta de @Riyad Kalla acima da qual eu testei também funciona bem, você pode fazer isso com Peter Walser, responda a @ Peter Walser em outra questão:
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/publicIcon getIcon(String name){Icon icon =null;
URL url =null;ImageIcon imgicon =null;BufferedImage scaledImage =null;try{
url = getClass().getResource(name);
icon =newImageIcon(url);if(icon ==null){System.out.println("Couldn't find "+ url);}BufferedImage bi =newBufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),BufferedImage.TYPE_INT_RGB);Graphics g = bi.createGraphics();// paint the Icon to the BufferedImage.
icon.paintIcon(null, g,0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon =newImageIcon(scaledImage);}catch(Exception e){System.out.println("Couldn't find "+ getClass().getName()+"/"+ name);
e.printStackTrace();}return imgicon;}publicstaticBufferedImage resizeImage (BufferedImage image,int areaWidth,int areaHeight){float scaleX =(float) areaWidth / image.getWidth();float scaleY =(float) areaHeight / image.getHeight();float scale =Math.min(scaleX, scaleY);int w =Math.round(image.getWidth()* scale);int h =Math.round(image.getHeight()* scale);int type = image.getTransparency()==Transparency.OPAQUE ?BufferedImage.TYPE_INT_RGB :BufferedImage.TYPE_INT_ARGB;boolean scaleDown = scale <1;if(scaleDown){// multi-pass bilinear div 2int currentW = image.getWidth();int currentH = image.getHeight();BufferedImage resized = image;while(currentW > w || currentH > h){
currentW =Math.max(w, currentW /2);
currentH =Math.max(h, currentH /2);BufferedImage temp =newBufferedImage(currentW, currentH, type);Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized,0,0, currentW, currentH,null);
g2.dispose();
resized = temp;}return resized;}else{Object hint = scale >2?RenderingHints.VALUE_INTERPOLATION_BICUBIC :RenderingHints.VALUE_INTERPOLATION_BILINEAR;BufferedImage resized =newBufferedImage(w, h,BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image,0,0, w, h,null);
g2.dispose();return resized;}}
Respostas:
Depois de carregar a imagem, você pode tentar:
fonte
FWIW Acabei de lançar (Apache 2, hospedado no GitHub) uma biblioteca simples de dimensionamento de imagens para Java chamada imgscalr (disponível no Maven central ).
A biblioteca implementa algumas abordagens diferentes para o dimensionamento de imagens (incluindo a abordagem incremental de Chris Campbell com alguns aprimoramentos menores) e escolherá a melhor abordagem para você, se você pedir, ou fornecerá a aparência mais rápida ou bonita (se você peça isso).
O uso é simples, apenas um monte de métodos estáticos. O caso de uso mais simples é:
Todas as operações mantêm as proporções originais da imagem; portanto, neste caso, você está solicitando ao imgscalr que redimensione sua imagem dentro de limites de 200 pixels de largura e 200 pixels de altura e, por padrão, selecionará automaticamente a abordagem mais rápida e bonita para isso, pois não foi possível. não especificado.
Percebo desde o início que isso se parece com autopromoção (é), mas gastei minha parte justa do tempo pesquisando exatamente esse mesmo assunto e continuei apresentando diferentes resultados / abordagens / pensamentos / sugestões e decidi sentar e escrever uma implementação simples que abordaria os casos de uso de 80 a 85% em que você tem uma imagem e provavelmente deseja uma miniatura para ela - o mais rápido possível ou o mais bonito possível (para aqueles que tentaram, você notará fazendo uma Graphics.drawImage, mesmo com interpolação BICUBIC em uma imagem pequena o suficiente, ainda parece lixo).
fonte
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
. Também gosto do seu jeito e acho que é mais simples.Thumbnailator é uma biblioteca de redimensionamento de imagem de código aberto para Java com uma interface fluente, distribuída sob a licença MIT.
Eu escrevi esta biblioteca porque criar miniaturas de alta qualidade em Java pode ser surpreendentemente difícil e o código resultante pode ser bastante confuso. Com o Thumbnailator, é possível expressar tarefas bastante complicadas usando uma API fluente simples.
Um exemplo simples
Para um exemplo simples, é possível obter uma imagem e redimensioná-la para 100 x 100 (preservando a proporção da imagem original) e salvando-a em um arquivo em uma única declaração:
Um exemplo avançado
A execução de tarefas complexas de redimensionamento é simplificada com a interface fluente do Thumbnailator.
Vamos supor que queremos fazer o seguinte:
0.85
,thumbnail.
anexados ao inícioTraduzido para o Thumbnailator, poderíamos executar o acima com o seguinte:
Uma observação sobre a qualidade e velocidade da imagem
Essa biblioteca também usa o método de dimensionamento bilinear progressivo destacado em Filthy Rich Clients por Chet Haase e Romain Guy, a fim de gerar miniaturas de alta qualidade e garantir um desempenho de tempo de execução aceitável.
fonte
Você não precisa de uma biblioteca para fazer isso. Você pode fazer isso com o próprio Java.
Chris Campbell tem um excelente e detalhado artigo sobre dimensionamento de imagens - consulte este artigo .
Chet Haase e Romain Guy também têm uma descrição detalhada e muito informativa do dimensionamento de imagens em seu livro Filthy Rich Clients .
fonte
O Java Advanced Imaging agora é de código aberto e fornece as operações necessárias.
fonte
Se você está lidando com imagens grandes ou deseja um resultado bonito, não é uma tarefa trivial em java. Simplesmente fazê-lo através de uma operação de revenda via Graphics2D não criará uma miniatura de alta qualidade. Você pode fazer isso usando JAI, mas requer mais trabalho do que você imagina para obter algo que pareça bom e a JAI tem o hábito desagradável de explodir nossa JVM com erros OutOfMemory.
Eu sugiro usar o ImageMagick como um executável externo, se você puder se safar. É simples de usar e faz o trabalho corretamente para que você não precise.
fonte
Se a opção imagemagick instalada no seu maschine for uma opção, eu recomendo o im4java . É uma camada de abstração muito fina na interface da linha de comando, mas faz seu trabalho muito bem.
fonte
A API Java não fornece um recurso de escala padrão para imagens e redução da qualidade da imagem.
Por causa disso, tentei usar o cvResize do JavaCV, mas parece causar problemas.
Encontrei uma boa biblioteca para dimensionamento de imagens: basta adicionar a dependência para "java-image-scaling" no seu pom.xml.
No repositório maven, você obterá a versão recente para isso.
Ex. No seu programa java
fonte
Você pode tentar usar o GraphicsMagick Image Processing System com o im4java como uma interface de linha de para Java.
Existem muitas vantagens do GraphicsMagick, mas uma por todas:
fonte
Image Magick foi mencionado. Existe um projeto de front end da JNI chamado JMagick. Não é um projeto particularmente estável (e se sabe que o Image Magick muda muito e até quebra a compatibilidade). Dito isso, tivemos uma boa experiência usando o JMagick e uma versão compatível do Image Magick em um ambiente de produção para executar o dimensionamento com alta taxa de transferência e baixa latência. A velocidade foi substancialmente melhor do que com uma biblioteca de gráficos Java que tentamos anteriormente.
http://www.jmagick.org/index.html
fonte
Basta usar a resposta de Burkhard, mas adicione esta linha depois de criar os gráficos:
Você também pode definir o valor como BICUBIC, ele produzirá uma imagem de melhor qualidade, mas é uma operação mais cara. Existem outras dicas de renderização que você pode definir, mas eu descobri que a interpolação produz o efeito mais notável. Lembre-se de que, se você quiser aumentar bastante o zoom, o código java provavelmente será muito lento. Acho que imagens maiores começam a produzir lag em torno de 300% de zoom, mesmo com todas as dicas de renderização definidas para otimizar a velocidade sobre a qualidade.
fonte
Você pode usar o Marvin (estrutura de processamento de imagem Java pura) para esse tipo de operação: http://marvinproject.sourceforge.net
Escala de plug-in: http://marvinproject.sourceforge.net/en/plugins/scale.html
fonte
Acontece que escrever um scaler de desempenho não é trivial. Eu fiz isso uma vez para um projeto de código aberto: ImageScaler .
Em princípio, 'java.awt.Image # getScaledInstance (int, int, int)' também faria o trabalho, mas há um bug desagradável com isso - consulte meu link para obter detalhes.
fonte
Eu desenvolvi uma solução com as classes disponíveis gratuitamente (AnimatedGifEncoder, GifDecoder e LWZEncoder) disponíveis para lidar com animação GIF.
Você pode fazer o download do jar jgifcode e executar a classe GifImageUtil. Link: http://www.jgifcode.com
fonte
você pode usar o seguinte produto popular: thumbnailator
fonte
Se você não deseja importar o imgScalr como a resposta de @Riyad Kalla acima da qual eu testei também funciona bem, você pode fazer isso com Peter Walser, responda a @ Peter Walser em outra questão:
fonte
Tente este método a seguir:
fonte