Introduction

There are many ways to scale/resize images in Java, but it could be very tricky to make some of them produce satisfying output in terms of image quality and also, processing time. There are core Java approaches to this issue, but third-party libraries offer more optimization in the background so that we can scale an image without any specific additional configuration and get a satisfying result. In this article, we'll show you the easiest ways to scale, and still, keep image quality. 

From the core Java features, there are two main ways to scale image - using Graphics2D and Image.getScaledInstance(). They provide us with certain configuration options called "hints" that can help us balance between processing time and output image quality. They're not in the scope of this article.

From third-party libraries, we chose ImageScalr and Thumbnailator as libraries that would pick the best possible algorithm for you, based on input parameters - current image and target width/height. We tried both of them and the result was very good, comparing to core Java features where you have to tweak, but still not get what you want. Both of them support all file types that are supported by ImageIO.

Scale image using Thumbnailator

First, we need to add Maven dependency for this one:

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.11</version>
</dependency>

This code sample shows how to scale image using Thumbnailator:

public class ThumbnailatorScaleExample {
    static BufferedImage scaleImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception {
        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
        Thumbnails.of(originalImage)
            .size(targetWidth, targetHeight)
            .outputFormat("JPEG")
            .outputQuality(0.99)
            .toOutputStream(byteOutputStream);
        byte[] data = byteOutputStream.toByteArray();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        return ImageIO.read(byteArrayInputStream);
    }

    public static void main(String[] args) throws Exception {
        BufferedImage originalImage = ImageIO.read(new File("path/to/your/input/file.jpg"));
        BufferedImage outputImage = resizeImage(originalImage, 300, 300);
        ImageIO.write(outputImage, "jpg", new File("path/to/your/output/file.jpg"));
    }
}

Scale image using ImgScalr

The Maven dependency for ImgScalr:

<dependency>
    <groupId>org.imgscalr</groupId>
    <artifactId>imgscalr-lib</artifactId>
    <version>4.2</version>
</dependency>

This code sample shows how to scale image using ImgScalr library:

public class ImagescalrScaleExample {
    static BufferedImage scaleImage(BufferedImage originalImage, int targetWidth) throws Exception {
        return Scalr.resize(originalImage, targetWidth);
    }

    public static void main(String[] args) throws Exception {
        BufferedImage originalImage = ImageIO.read(new File("path/to/your/input/image.jpg"));
        BufferedImage outputImage = scaleImage(originalImage, 300, 300);
        ImageIO.write(outputImage, "jpg", new File("path/to/your/output/image.jpg"));
    }
}

Introduction

In this quick example, we'll show how to read Gmail using Java and javax.mail library. We'll use IMAP since it's more flexible than POP3 in terms of folder and message manipulation. We'll read message headers, and after that, we'll mark it as "seen" that will indicate that message is read.

Read Gmail using Java

Maven dependency:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>

Notice that IMAP uses port 993 instead of 995 reserved for POP3. Change values of username and password variables according to your account. It's very useful to use Google application password (password intended only for API access), you can find out more about it here.

package com.example;

import java.util.Properties;

import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.FlagTerm;

public class ReadMailExample {


	public static void check(String host, String storeType, String user, String password) {
		try {

			// create properties
			Properties properties = new Properties();

			properties.put("mail.imap.host", host);
			properties.put("mail.imap.port", "993");
			properties.put("mail.imap.starttls.enable", "true");
			properties.put("mail.imap.ssl.trust", host);

			Session emailSession = Session.getDefaultInstance(properties);

			// create the imap store object and connect to the imap server
			Store store = emailSession.getStore("imaps");

			store.connect(host, user, password);

			// create the inbox object and open it
			Folder inbox = store.getFolder("Inbox");
			inbox.open(Folder.READ_WRITE);

			// retrieve the messages from the folder in an array and print it
			Message[] messages = inbox.search(new FlagTerm(new Flags(Flag.SEEN), false));
			System.out.println("messages.length---" + messages.length);

			for (int i = 0, n = messages.length; i < n; i++) {
				Message message = messages[i];
				message.setFlag(Flag.SEEN, true);
				System.out.println("---------------------------------");
				System.out.println("Email Number " + (i + 1));
				System.out.println("Subject: " + message.getSubject());
				System.out.println("From: " + message.getFrom()[0]);
				System.out.println("Text: " + message.getContent().toString());

			}

			inbox.close(false);
			store.close();

		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		} catch (MessagingException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {

		String host = "imap.gmail.com";
		String mailStoreType = "imap";
		String username = "yourmailaddress@gmail.com";
		String password = "yourpassword";

		check(host, mailStoreType, username, password);

	}
}

After you set params, you'll get a response like this:

messages.length---1
---------------------------------
Email Number 1
Subject: test1
From: John Johnson <john@gmail.com>
Text: javax.mail.internet.MimeMultipart@6a78afa0

Possible issues

In case that you have the following exception while using this code, it is very possible that your antivirus is blocking the application. I was using Avast and after clicking "Disable for 10 minutes" in Avast Shield Control it worked fine. To avoid doing this every time you use your application, try adding Java to antivirus exceptions. 

javax.mail.MessagingException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
  nested exception is:
	javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:742)
	at javax.mail.Service.connect(Service.java:366)
	at javax.mail.Service.connect(Service.java:246)
	at com.headsoft.cloud.items.service.MailServiceImpl.check(MailServiceImpl.java:37)
	at com.headsoft.cloud.items.service.MailServiceImpl.main(MailServiceImpl.java:77)
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:324)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:262)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:645)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:464)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:360)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1460)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1368)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:437)
	at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:626)
	at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:400)
	at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
	at com.sun.mail.iap.Protocol.<init>(Protocol.java:134)
	at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:131)
	at com.sun.mail.imap.IMAPStore.newIMAPProtocol(IMAPStore.java:763)
	at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:698)
	... 4 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:438)
	at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:305)
	at java.base/sun.security.validator.Validator.validate(Validator.java:264)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:629)
	... 21 more

Newsletter

Please enable the javascript to submit this form