Pergunta

Eu preciso para redimensionar arquivos PNG, JPEG e GIF. Como posso fazer isso usando Java?

Foi útil?

Solução

Depois de carregar a imagem que você pode tentar:

BufferedImage createResizedCopy(Image originalImage, 
            int scaledWidth, int scaledHeight, 
            boolean preserveAlpha)
    {
        System.out.println("resizing...");
        int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
        Graphics2D g = scaledBI.createGraphics();
        if (preserveAlpha) {
            g.setComposite(AlphaComposite.Src);
        }
        g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null); 
        g.dispose();
        return scaledBI;
    }

Outras dicas

FWIW I acaba de lançar (Apache 2, hospedado no GitHub) uma biblioteca de imagem-scaling simples para Java chamado imgscalr (disponível no Maven central).

Os biblioteca implementa algumas abordagens diferentes para a imagem-scaling (incluindo abordagem incremental de Chris Campbell com um menor poucas melhorias) e que quer escolher a abordagem mais ideal para você, se você pedir para ele, ou dar-lhe o mais rápido ou mais bonito (se você pedir isso).

O uso é morto simples, apenas um monte de métodos estáticos. O caso de uso mais simples é:

BufferedImage scaledImage = Scalr.resize(myImage, 200);

Todas as operações de manter as proporções originais da imagem, por isso, neste caso, você está pedindo imgscalr para redimensionar a sua imagem dentro de limites de 200 pixels de largura e 200 pixels de altura e por padrão ele irá selecionar automaticamente o melhor para o futuro e mais rápida abordagem para esse uma vez que não foi especificado.

Eu percebo no início Isto parece auto-promoção (é), mas eu passei o meu quinhão de tempo pesquisando o mesmo assunto exato e manteve chegando com diferentes resultados / abordagens / pensamentos / sugestões e decidiu sentar-se e escrever uma aplicação simples que iria abordar que 80-85% casos de uso em que você tem uma imagem e, provavelmente, querem uma miniatura para ele - ou o mais rápido possível ou tão bonito quanto possível (para aqueles que têm tentado, você 'aviso ll fazendo um Graphics.drawImage mesmo com bicubic interpolação para uma imagem bastante pequeno, ele ainda se parece com o lixo).

Thumbnailator é uma imagem de código aberto biblioteca redimensionamento para Java com uma interface fluente, distribuído sob a licença MIT

Eu escrevi esta biblioteca porque fazer miniaturas de alta qualidade em Java pode ser surpreendentemente difícil, e o código resultante pode ser bastante confuso. Com Thumbnailator, é possível expressar tarefas bastante complicadas usando uma API fluente simples.

Um exemplo simples

Para um exemplo simples, tendo uma imagem e redimensioná-la para 100 x 100 (mantendo a proporção da imagem original), e salvá-lo para um arquivo pode alcançado em uma única instrução:

Thumbnails.of("path/to/image")
    .size(100, 100)
    .toFile("path/to/thumbnail");

Um exemplo avançado

Execução de tarefas de redimensionamento complexos é simplificada com interface fluente do Thumbnailator.

Vamos supor que queremos fazer o seguinte:

  1. tomar as imagens em um diretório e,
  2. redimensioná-las para 100 x 100, com a relação entre a imagem original,
  3. save-los todos para JPEGs com configurações de 0.85 qualidade,
  4. em que os nomes de arquivo são tomadas a partir do original com thumbnail. anexado ao início

Traduzido para Thumbnailator, seríamos capazes de realizar a acima com o seguinte:

Thumbnails.of(new File("path/to/directory").listFiles())
    .size(100, 100)
    .outputFormat("JPEG")
    .outputQuality(0.85)
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

Uma nota sobre a qualidade de imagem e velocidade

Esta biblioteca também usa o scaling bilinear progressiva método em destaque na Filthy Rich Clients por Chet Haase e Romain Guy em a fim de gerar miniaturas de alta qualidade, garantindo o desempenho de tempo de execução aceitável.

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 write-up detalhado sobre o escalonamento de imagens - veja este artigo .

Chet Haase e Romain Guy também têm um detalhado e muito informativo write-up de dimensionamento de imagem em seu livro, clientes podre de rico .

Java Advanced Imaging agora é open source e fornece as operações que você precisa.

Se você está lidando com grandes imagens ou quer um bom olhar resultado não é uma tarefa trivial em java. Basta fazê-lo através de um op rescale via Graphics2D não vai criar uma miniatura de alta qualidade. Você pode fazer isso usando JAI, mas exige mais trabalho do que você pode imaginar para obter algo que parece ser bom e JAI tem o mau hábito de explodir nossa seu JVM com erros OutOfMemory.

Eu sugiro usar ImageMagick como um executável externo, se você pode ir longe com ele. É simples de usar e que faz o trabalho certo para que você não tem que.

Se, tendo imagemagick instalado no seu maschine é uma opção, eu recomendo im4java . É uma camada de abstração muito fina sobre a interface de linha de comando, mas faz o seu trabalho muito bem.

A Java API não fornece uma característica de escala padrão para imagens e downgrade de qualidade de imagem.

Devido a isso eu tentei usar cvResize de JavaCV mas parece causar problemas.

Eu encontrei uma biblioteca bom para dimensionamento da imagem: basta adicionar a dependência para "java-image-scaling" em seu pom.xml.

<dependency>
    <groupId>com.mortennobel</groupId>
    <artifactId>java-image-scaling</artifactId>
    <version>0.8.6</version>
</dependency>

No repositório maven você vai ter a versão mais recente para isso.

Ex. Em seu programa java

ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);

Você poderia tentar usar GraphicsMagick Imagem Sistema de Processamento de com im4java como uma interface de linha de comand para Java.

Há uma série de vantagens de GraphicsMagick, mas um por todos:

  • GM é usado para milhares de milhões de processos de arquivos na maior foto do mundo sites (por exemplo, Flickr e Etsy).

Imagem Magick foi mencionado. Há um projeto de front-end JNI chamado JMagick. Não é um projeto particularmente estável (e Imagem em si Magick tem sido conhecida a mudar muita coisa e até mesmo quebrar a compatibilidade). Dito isto, tivemos uma boa experiência usando JMagick e uma versão compatível do Imagem Magick em um ambiente de produção para executar escala em um alto rendimento, baixa taxa de latência. A velocidade era substancialmente melhor, em seguida, com uma biblioteca de gráficos tudo Java que anteriormente tentou.

http://www.jmagick.org/index.html

Basta usar a resposta de Burkhard mas adicione esta linha depois de criar os gráficos:

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

Você também pode definir o valor para Bicubic, que irá produzir uma imagem de melhor qualidade, mas é uma operação mais caro. Existem outras dicas de renderização que pode definir, mas eu descobri que a interpolação produz o efeito mais notável. Tenha em mente se você quiser fazer zoom em um lote, código java provavelmente será muito lento. I encontrar imagens maiores começam a produzir lag cerca de 300% de zoom, mesmo com todas as dicas de renderização definidos para otimizar a velocidade em detrimento da qualidade.

Você pode usar Marvin (quadro puro processamento de imagem Java) para este tipo de operação: http://marvinproject.sourceforge.net

Escala plug-in: http://marvinproject.sourceforge.net/en/plugins/scale.html

Acontece que escrever um escalonamento de performance não é trivial. Eu fiz isso uma vez para um projeto open source: ImageScaler .

Em princípio 'java.awt.Image # getScaledInstance (int, int, int)' iria fazer o trabalho bem, mas há um bug desagradável com isso -. Referem-se ao meu link para mais detalhes

Eu desenvolvi uma solução com as classes livremente disponíveis (AnimatedGifEncoder, GifDecoder e LWZEncoder) disponíveis para o tratamento de GIF Animation.
Você pode baixar o jar jgifcode e executar a classe GifImageUtil. Link: http://www.jgifcode.com

Você pode usar seguinte produto popular: thumbnailator

Se você não deseja importar imgScalr como @Riyad Kalla resposta acima que eu testei também funciona bem , você consegue fazer isso tirada resposta Peter Walser @ Peter Walser em outra questão embora:

 /**
     * 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.
     */
    public Icon getIcon(String name) {
        Icon icon = null;
        URL url = null;
        ImageIcon imgicon = null;
        BufferedImage scaledImage = null;
        try {
            url = getClass().getResource(name);

            icon = new ImageIcon(url);
            if (icon == null) {
                System.out.println("Couldn't find " + url);
            }

            BufferedImage bi = new BufferedImage(
                    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 = new ImageIcon(scaledImage);

        } catch (Exception e) {
            System.out.println("Couldn't find " + getClass().getName() + "/" + name);
            e.printStackTrace();
        }
        return imgicon;
    }

 public static BufferedImage 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 2
            int 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 = new BufferedImage(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 = new BufferedImage(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;
        }
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top