Bagaimana Saya Bisa Mengubah Ukuran Gambar Menggunakan Java?

1. Perkenalan

Dalam tutorial ini, kita akan belajar bagaimana mengubah ukuran (skala) gambar menggunakan Java. Kami akan menjelajahi Java inti dan pustaka pihak ketiga sumber terbuka yang menawarkan fitur pengubahan ukuran gambar.

Penting untuk disebutkan bahwa kami dapat mengubah skala gambar ke atas dan ke bawah. Dalam contoh kode dalam tutorial ini, kami akan mengubah ukuran gambar menjadi ukuran yang lebih kecil karena, dalam praktiknya, itulah skenario yang paling umum.

2. Ubah Ukuran Gambar Menggunakan Core Java

Core Java menawarkan opsi berikut untuk mengubah ukuran gambar:

  • Ubah ukuran menggunakan java.awt.Graphics2D
  • Ubah ukuran menggunakan Image # getScaledInstance

2.1. java.awt.Graphics2D

Graphics2D adalah kelas dasar untuk merender bentuk, teks, dan gambar 2 dimensi pada platform Java.

Mari kita mulai dengan mengubah ukuran gambar menggunakan Graphics2D :

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

Mari kita lihat seperti apa gambar itu sebelum dan sesudah mengubah ukuran:

The BufferedImage.TYPE_INT_RGB parameter menunjukkan model warna gambar. Daftar lengkap nilai yang tersedia tersedia di dokumentasi resmi Java BufferedImage .

Graphics2D menerima parameter tambahan yang disebut RenderingHints . Kami menggunakan RenderingHints untuk mempengaruhi berbagai aspek pemrosesan gambar dan yang terpenting kualitas gambar dan waktu pemrosesan.

Kita bisa menambahkan RenderingHint menggunakan metode setRenderingHint :

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

Daftar lengkap RenderingHints dapat ditemukan di tutorial Oracle ini.

2.2. Image.getScaledInstance ()

Pendekatan menggunakan Gambar ini sangat sederhana dan menghasilkan gambar dengan kualitas yang memuaskan:

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException { Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT); BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB); outputImage.getGraphics().drawImage(resultingImage, 0, 0, null); return outputImage; }

Mari kita lihat apa yang terjadi dengan gambar sesuatu yang enak:

Kita juga bisa mengarahkan mekanisme penskalaan untuk menggunakan salah satu pendekatan yang tersedia dengan menyediakan metode getScaledInstance () dengan tanda yang menunjukkan jenis algoritme yang akan digunakan untuk kebutuhan pengambilan sampel ulang gambar kita:

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

Semua flag yang tersedia dijelaskan dalam dokumentasi resmi Java Image.

3. Imgscalr

Imgscalr menggunakan Graphic2D di latar belakang. Ini memiliki API sederhana dengan beberapa metode berbeda untuk mengubah ukuran gambar.

Imgscalr memberi kami hasil terbaik, hasil tercepat, atau hasil seimbang tergantung pada opsi penskalaan yang kami pilih. Fitur manipulasi gambar lainnya juga tersedia - seperti cropping dan rotasi. Mari tunjukkan cara kerjanya dalam contoh sederhana.

Kami akan menambahkan dependensi Maven berikut:

 org.imgscalr imgscalr-lib 4.2 

Periksa Maven Central untuk versi terbaru.

Cara termudah untuk menggunakan Imgscalr adalah:

BufferedImage simpleResizeImage(BufferedImage originalImage, int targetWidth) throws Exception { return Scalr.resize(originalImage, targetWidth); }

Di mana originalImage adalah BufferedImage yang akan diubah ukurannya dan targetWidth adalah lebar gambar hasil. Pendekatan ini akan mempertahankan proporsi gambar asli dan menggunakan parameter default - Method.AUTOMATIC dan Mode.AUTOMATIC .

Bagaimana dengan gambaran buah yang enak? Ayo lihat:

Pustaka juga memungkinkan beberapa opsi konfigurasi, dan, ini menangani transparansi gambar di latar belakang.

Parameter terpenting adalah:

  • mode - digunakan untuk menentukan mode pengubahan ukuran yang akan digunakan algoritme. Misalnya, kita dapat menentukan apakah kita ingin mempertahankan proporsi gambar (opsinya adalah AUTOMATIC, FIT_EXACT, FIT_TO_HEIGHT, dan FIT_TO_WIDTH )
  • metode - menginstruksikan proses pengubahan ukuran sehingga fokusnya adalah pada kecepatan, kualitas, atau keduanya. Nilai yang memungkinkan adalah AUTOMATIC, BALANCED, QUALITY, SPEED, ULTRA_QUALITY

Ini juga memungkinkan untuk menentukan properti pengubah ukuran tambahan yang akan memberi kita logging atau mengarahkan perpustakaan untuk melakukan beberapa modifikasi warna pada gambar (membuatnya lebih terang, lebih gelap, skala abu-abu, dan sebagainya).

Mari gunakan parameterisasi metode resize () penuh :

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

Dan sekarang kita mendapatkan:

Imgscalr bekerja dengan semua file yang didukung oleh Java Image IO - JPG, BMP, JPEG, WBMP, PNG, dan GIF.

4. Thumbnailator

Thumbnailator adalah pustaka pengubah ukuran gambar sumber terbuka untuk Java yang menggunakan penskalaan bilinear progresif. Ini mendukung JPG, BMP, JPEG, WBMP, PNG, dan GIF.

We'll include it in our project by adding the following Maven dependency to our pom.xml:

 net.coobird thumbnailator 0.4.11 

Available dependency versions can be found on Maven Central.

It has a very simple API and allows us to set output quality in percentage:

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Thumbnails.of(originalImage) .size(targetWidth, targetHeight) .outputFormat("JPEG") .outputQuality(1) .toOutputStream(outputStream); byte[] data = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(data); return ImageIO.read(inputStream); }

Let's see how this smiling photograph looks before and after resizing:

It also has an option for batch processing:

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

As Imgscalr, Thumblinator works with all files supported by Java Image IO – JPG, BMP, JPEG, WBMP, PNG, and GIF.

5. Marvin

Marvin is a handy tool for image manipulation and it offers a lot of useful basic (crop, rotate, skew, flip, scale) and advanced (blur, emboss, texturing) features.

As before, we'll add Maven dependencies needed for Marvin resizing:

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

Available Marvin dependency versions can be found on Maven Central, along with the Marvin Plugins versions.

The downside of Marvin is that it doesn't offer an additional scaling configuration. Also, the scale method requires an image and image clone which is a bit cumbersome:

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) { MarvinImage image = new MarvinImage(originalImage); Scale scale = new Scale(); scale.load(); scale.setAttribute("newWidth", targetWidth); scale.setAttribute("newHeight", targetHeight); scale.process(image.clone(), image, null, null, false); return image.getBufferedImageNoAlpha(); }

Let's now resize an image of a flower and see how it goes:

6. Best Practice

Image processing is an expensive operation in terms of resources, so picking the highest quality is not necessarily the best option when we don't really need it.

Let's see the performance of all of the approaches. We took one 1920×1920 px image, and scaled it to 200×200 px. The resulting observed times are as follows:

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

Selain itu, saat menentukan lebar dan tinggi gambar target, kita harus memperhatikan rasio aspek gambar. Dengan cara ini gambar akan mempertahankan proporsi aslinya dan tidak akan melebar.

7. Kesimpulan

Artikel ini mengilustrasikan beberapa cara untuk mengubah ukuran gambar di Java. Kami juga mempelajari berapa banyak faktor berbeda yang dapat memengaruhi proses pengubahan ukuran.

Contoh kode lengkap tersedia di GitHub.