Hoe kan ik het formaat van een afbeelding wijzigen met Java?

1. Inleiding

In deze tutorial gaan we leren hoe we een afbeelding kunnen vergroten / verkleinen (schalen) met behulp van Java. We zullen zowel kern Java als open-source bibliotheken van derden verkennen die de functie voor het wijzigen van het formaat van afbeeldingen bieden.

Het is belangrijk om te vermelden dat we afbeeldingen zowel naar boven als naar beneden kunnen schalen. In de codevoorbeelden in deze zelfstudie veranderen we de grootte van afbeeldingen naar kleinere formaten, aangezien dit in de praktijk het meest voorkomende scenario is.

2. Pas het formaat van een afbeelding aan met behulp van Core Java

Core Java biedt de volgende opties om het formaat van afbeeldingen te wijzigen:

  • Formaat wijzigen met java.awt.Graphics2D
  • Formaat wijzigen met Afbeelding # getScaledInstance

2.1. java.awt.Graphics2D

Grafische 2D is de fundamentele klasse voor het renderen van tweedimensionale vormen, tekst en afbeeldingen op het Java-platform.

Laten we beginnen met het vergroten of verkleinen van een afbeelding met Grafische 2D:

BufferedImage resizeImage (BufferedImage originalImage, int targetWidth, int targetHeight) gooit IOException {BufferedImage resizedImage = nieuwe BufferedImage (targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2D = resizedImage.createGraphics (); graphics2D.drawImage (originalImage, 0, 0, targetWidth, targetHeight, null); graphics2D.dispose (); retourneer resizedImage; }

Laten we eens kijken hoe de afbeelding eruitziet voor en na het wijzigen van het formaat:

De BufferedImage.TYPE_INT_RGB parameter geeft het kleurmodel van de afbeelding aan. Een volledige lijst met beschikbare waarden is beschikbaar in de officiële Java BufferedImage documentatie.

Grafische 2D accepteert aanvullende parameters genaamd RenderingHints. We gebruiken RenderingHints verschillende aspecten van beeldverwerking beïnvloeden en vooral beeldkwaliteit en verwerkingstijd.

We kunnen een RenderingHint de ... gebruiken setRenderingHint methode:

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

Een volledige lijst van RenderingHints vindt u in deze Oracle-tutorial.

2.2. Image.getScaledInstance ()

Deze benadering gebruikt Beeld is heel eenvoudig en het levert afbeeldingen van bevredigende kwaliteit op:

BufferedImage resizeImage (BufferedImage originalImage, int targetWidth, int targetHeight) gooit IOException {Image resultImage = originalImage.getScaledInstance (targetWidth, targetHeight, Image.SCALE_DEFAULT); BufferedImage outputImage = nieuwe BufferedImage (targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB); outputImage.getGraphics (). drawImage (resultImage, 0, 0, null); retourneer outputImage; }

Laten we eens kijken wat er gebeurt met een foto van iets lekkers:

We kunnen het schaalmechanisme ook sturen om een ​​van de beschikbare benaderingen te gebruiken door de getScaledInstance () methode met een vlag die het type algoritme aangeeft dat moet worden gebruikt voor onze beeldresamplingbehoeften:

Afbeelding resulterendeImage = originalImage.getScaledInstance (targetWidth, targetHeight, Image.SCALE_SMOOTH);

Alle beschikbare vlaggen worden beschreven in de officiële Java Image-documentatie.

3. Imgscalr

Imgscalr gebruikt Graphic2D op de achtergrond. Het heeft een eenvoudige API met een paar verschillende methoden om het formaat van afbeeldingen te wijzigen.

Imgscalr biedt ons ofwel het best uitziende resultaat, het snelste resultaat of een uitgebalanceerd resultaat, afhankelijk van de schaaloptie die we kiezen. Er zijn ook andere functies voor beeldmanipulatie beschikbaar, zoals die voor bijsnijden en roteren. Laten we in een eenvoudig voorbeeld laten zien hoe het werkt.

We zullen de volgende Maven-afhankelijkheid toevoegen:

 org.imgscalr imgscalr-lib 4.2 

Controleer Maven Central voor de nieuwste versie.

De eenvoudigste manier om Imgscalr te gebruiken is:

BufferedImage simpleResizeImage (BufferedImage originalImage, int targetWidth) genereert Uitzondering {return Scalr.resize (originalImage, targetWidth); }

Waar Originele afbeelding is de BufferedImage worden aangepast en targetWidth is de breedte van een resultaatafbeelding. Deze benadering behoudt de oorspronkelijke verhoudingen van de afbeelding en gebruikt standaardparameters - Methode AUTOMATISCH en Modus AUTOMATISCH.

Hoe gaat het met een foto van heerlijk fruit? Laten we kijken:

De bibliotheek biedt ook meerdere configuratie-opties en behandelt de beeldtransparantie op de achtergrond.

De belangrijkste parameters zijn:

  • modus - gebruikt om de formaatmodi te definiëren die het algoritme zal gebruiken. We kunnen bijvoorbeeld definiëren of we de verhoudingen van de afbeelding willen behouden (opties zijn AUTOMATIC, FIT_EXACT, FIT_TO_HEIGHT en FIT_TO_WIDTH)
  • methode - instrueert het proces voor het wijzigen van de grootte, zodat de focus ligt op snelheid, kwaliteit of beide. Mogelijke waarden zijn AUTOMATISCH, EVENWICHTIG, KWALITEIT, SNELHEID, ULTRA_QUALITY

Het is ook mogelijk om extra eigenschappen voor het wijzigen van de grootte te definiëren die ons voorzien van logboekregistratie of om de bibliotheek te instrueren om enkele kleuraanpassingen aan de afbeelding uit te voeren (maak deze lichter, donkerder, grijstinten, enzovoort).

Laten we het volledige gebruiken formaat wijzigen () methode parametrering:

BufferedImage resizeImage (BufferedImage originalImage, int targetWidth, int targetHeight) genereert uitzondering {return Scalr.resize (originalImage, Scalr.Method.AUTOMATIC, Scalr.Mode.AUTOMATIC, targetWidth, targetHeight, Scalr.OP_ANTIALIAS); }

En nu krijgen we:

Imgscalr werkt met alle bestanden die worden ondersteund door Java Image IO - JPG, BMP, JPEG, WBMP, PNG en GIF.

4. Thumbnailator

Thumbnailator is een open-source bibliotheek voor het wijzigen van de grootte van afbeeldingen voor Java die gebruikmaakt van progressieve bilineaire schaling. Het ondersteunt JPG, BMP, JPEG, WBMP, PNG en GIF.

We nemen het op in ons project door de volgende Maven-afhankelijkheid toe te voegen aan ons pom.xml:

 net.coobird thumbnailator 0.4.11 

Beschikbare afhankelijkheidsversies zijn te vinden op Maven Central.

Het heeft een heel eenvoudige API en stelt ons in staat om de uitvoerkwaliteit in procenten in te stellen:

BufferedImage resizeImage (BufferedImage originalImage, int targetWidth, int targetHeight) gooit uitzondering {ByteArrayOutputStream outputStream = nieuwe ByteArrayOutputStream (); Thumbnails.of (originalImage) .size (targetWidth, targetHeight) .outputFormat ("JPEG") .outputQuality (1) .toOutputStream (outputStream); byte [] gegevens = outputStream.toByteArray (); ByteArrayInputStream inputStream = nieuwe ByteArrayInputStream (data); retourneer ImageIO.read (inputStream); }

Laten we eens kijken hoe deze lachende foto eruitziet voor en na het wijzigen van het formaat:

Het heeft ook een optie voor batchverwerking:

Thumbnails.of (nieuw bestand ("pad / naar / directory"). ListFiles ()) .size (300, 300) .outputFormat ("JPEG") .outputQuality (0.80) .toFiles (Rename.PREFIX_DOT_THUMBNAIL);

Als Imgscalr werkt Thumblinator met alle bestanden die worden ondersteund door Java Image IO - JPG, BMP, JPEG, WBMP, PNG en GIF.

5. Marvin

Marvin is een handig hulpmiddel voor beeldmanipulatie en het biedt veel handige basisfuncties (bijsnijden, roteren, scheeftrekken, spiegelen, schalen) en geavanceerde (vervagen, reliëf, textuur) functies.

Zoals eerder zullen we Maven-afhankelijkheden toevoegen die nodig zijn voor het wijzigen van de grootte van Marvin:

 com.github.downgoon marvin 1.5.5 pom com.github.downgoon MarvinPlugins 1.5.5 

Beschikbare versies van Marvin-afhankelijkheid zijn te vinden op Maven Central, samen met de versies van Marvin Plugins.

Het nadeel van Marvin is dat het geen extra schaalconfiguratie biedt. De schaalmethode vereist ook een afbeelding en een afbeeldingskloon die een beetje omslachtig is:

BufferedImage resizeImage (BufferedImage originalImage, int targetWidth, int targetHeight) {MarvinImage image = nieuwe MarvinImage (originalImage); Schaal schaal = nieuwe schaal (); scale.load (); scale.setAttribute ("newWidth", targetWidth); scale.setAttribute ("newHeight", targetHeight); scale.process (image.clone (), afbeelding, null, null, false); retourneer image.getBufferedImageNoAlpha (); }

Laten we nu het formaat van een afbeelding van een bloem wijzigen en kijken hoe het gaat:

6. Beste praktijken

Beeldverwerking is een dure operatie in termen van middelen, dus het kiezen van de hoogste kwaliteit is niet per se de beste optie als we die niet echt nodig hebben.

Laten we eens kijken naar de prestaties van alle benaderingen. We hebben er een genomen 1920 × 1920 px afbeelding, en geschaald naar 200 × 200 px. De resulterende geobserveerde tijden zijn als volgt:

  • java.awt.Graphics2D - 34 ms
  • Image.getScaledInstance () - 235 ms
  • Imgscalr - 143ms
  • Thumbnailator - 547ms
  • Marvin - 361ms

Bij het definiëren van de doelbeeldbreedte en -hoogte, we moeten letten op de beeldverhouding. Op deze manier behoudt het beeld zijn oorspronkelijke verhoudingen en wordt het niet uitgerekt.

7. Conclusie

Dit artikel illustreert een paar manieren om het formaat van een afbeelding in Java te wijzigen. We hebben ook geleerd hoeveel verschillende factoren het proces van verkleinen kunnen beïnvloeden.

Volledige codevoorbeelden zijn beschikbaar op GitHub.