In the tutorial Send e-mail with attachment in Java, we discussed how to attach files to an e-mail message using JavaMail. In this article, we will use a similar technique plus some modification in order to embed some images directly into the message. The embedded images are called inline attachments which users see the images right inside the e-mail’s content. That’s different with regular attachments which the users have to download and open them manually.

The message must in HTML format in order to have inline images, so we should set content type of the message as follows:

MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent(htmlMessage, "text/html");
Where htmlMessage is a String represents content of the message with HTML tags:

String htmlMessage = "<html>Hi there,<br>";
htmlMessage += "See this cool pic: <img src=\"cid:AbcXyz123\" />";
htmlMessage += "</html>";
As you notice in the HTML code above, we use the <img> tag to include an image, but its src attribute does not point to name of the image. Instead, the src attribute must refer to Content-ID header’s value of a MIME part which contains the actual image, in the following form:

src=”cid:<content_id>

Then the image part should be created as follows:

MimeBodyPart imagePart = new MimeBodyPart();
imagePart.setHeader("Content-ID", "AbcXyz123");
imagePart.setDisposition(MimeBodyPart.INLINE);
// attach the image file
imagePart.attachFile(imageFilePath);
The value of the Content-ID header must be a unique identifier. This convention is described in the RFC 2387.

Now let’s create a real example with a utility class and a test program.

 

1. Coding An Email Utility class

We create an out-of-the-box utility class as follows:

package net.codejava.mail;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 * This utility class provides a functionality to send an HTML e-mail message
 * with embedded images.
 * @author www.codejava.net
 *
 */
public class EmbeddedImageEmailUtil {

	/**
	 * Sends an HTML e-mail with inline images.
	 * @param host SMTP host
	 * @param port SMTP port
	 * @param userName e-mail address of the sender's account 
	 * @param password password of the sender's account
	 * @param toAddress e-mail address of the recipient
	 * @param subject e-mail subject
	 * @param htmlBody e-mail content with HTML tags
	 * @param mapInlineImages 
	 * 			key: Content-ID
	 * 			value: path of the image file
	 * @throws AddressException
	 * @throws MessagingException
	 */
	public static void send(String host, String port,
			final String userName, final String password, String toAddress,
			String subject, String htmlBody, 
			Map<String, String> mapInlineImages)
				throws AddressException, MessagingException {
		// sets SMTP server properties
		Properties properties = new Properties();
		properties.put("mail.smtp.host", host);
		properties.put("mail.smtp.port", port);
		properties.put("mail.smtp.auth", "true");
		properties.put("mail.smtp.starttls.enable", "true");
		properties.put("mail.user", userName);
		properties.put("mail.password", password);

		// creates a new session with an authenticator
		Authenticator auth = new Authenticator() {
			public PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(userName, password);
			}
		};
		Session session = Session.getInstance(properties, auth);

		// creates a new e-mail message
		Message msg = new MimeMessage(session);

		msg.setFrom(new InternetAddress(userName));
		InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
		msg.setRecipients(Message.RecipientType.TO, toAddresses);
		msg.setSubject(subject);
		msg.setSentDate(new Date());

		// creates message part
		MimeBodyPart messageBodyPart = new MimeBodyPart();
		messageBodyPart.setContent(htmlBody, "text/html");

		// creates multi-part
		Multipart multipart = new MimeMultipart();
		multipart.addBodyPart(messageBodyPart);

		// adds inline image attachments
		if (mapInlineImages != null && mapInlineImages.size() > 0) {
			Set<String> setImageID = mapInlineImages.keySet();
			
			for (String contentId : setImageID) {
				MimeBodyPart imagePart = new MimeBodyPart();
				imagePart.setHeader("Content-ID", "<" + contentId + ">");
				imagePart.setDisposition(MimeBodyPart.INLINE);
				
				String imageFilePath = mapInlineImages.get(contentId);
				try {
					imagePart.attachFile(imageFilePath);
				} catch (IOException ex) {
					ex.printStackTrace();
				}

				multipart.addBodyPart(imagePart);
			}
		}

		msg.setContent(multipart);

		Transport.send(msg);
	}
}


Clients can call the static method send() to send an e-mail message in HTML format with embedded images passed via the parameter mapInlineImages. So it’s convenient for embedding an image as follows:

Map<String, String> inlineImages = new HashMap<String, String>();
inlineImages.put("ID123456", "D:/Images/stockchart.jpg");
Note this line:

imagePart.setHeader("Content-ID", "<" + contentId + ">");
The reason that we have to wrap the contentIdbetween the “<” and “>” is because some e-mail clients (such as Gmail) won’t show the inline images without those angle brackets.

 

2. Coding A Test program for embedding images into emails

Code the test program as follows:

package net.codejava.mail;

import java.util.HashMap;
import java.util.Map;

/**
 * This program tests out the EmbeddedImageEmailUtil utility class.
 * @author www.codejava.net
 *
 */
public class InlineImageEmailTester {

	/**
	 * main entry of the program
	 */
	public static void main(String[] args) {
		// SMTP info
		String host = "smtp.gmail.com";
		String port = "587";
		String mailFrom = "YOUR_EMAIL";
		String password = "YOUR_PASSWORD";

		// message info
		String mailTo = "YOUR_RECIPIENT";
		String subject = "Test e-mail with inline images";
		StringBuffer body
			= new StringBuffer("<html>This message contains two inline images.<br>");
		body.append("The first image is a chart:<br>");
		body.append("<img src=\"cid:image1\" width=\"30%\" height=\"30%\" /><br>");
		body.append("The second one is a cube:<br>");
		body.append("<img src=\"cid:image2\" width=\"15%\" height=\"15%\" /><br>");
		body.append("End of message.");
		body.append("</html>");

		// inline images
		Map<String, String> inlineImages = new HashMap<String, String>();
		inlineImages.put("image1", "E:/Test/chart.png");
		inlineImages.put("image2", "E:/Test/cube.jpg");

		try {
			EmbeddedImageEmailUtil.send(host, port, mailFrom, password, mailTo,
				subject, body.toString(), inlineImages);
			System.out.println("Email sent.");
		} catch (Exception ex) {
			System.out.println("Could not send email.");
			ex.printStackTrace();
		}
	}
}
 

In this test program, we configure SMTP settings for a GMail account and compose an HTML message with two inline images image1 and image2 which correspond to two actual images file chart.png and cube.jpg.

When running this program, we got the following result in GMail:

email embedded images in GMail

And in Microsoft Outlook:

email embedded images in Outlook

 

NOTES:

You need to use JavaMail jar files. If you use Maven, add the following dependency to the pom.xml file:

<dependency>
	<groupId>com.sun.mail</groupId>
	<artifactId>javax.mail</artifactId>
	<version>1.6.2</version>
</dependency>
This will add the javax.mail-VERSION.jar and activation-VERSION.jar to the project's classpath. If you have to add them manually, download from JavaMail Project page.

 

Other JavaMail Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Attachments:
Download this file (EmbeddedImageEmailUtil.java)EmbeddedImageEmailUtil.java[Utility class]3 kB
Download this file (InlineImageEmailTester.java)InlineImageEmailTester.java[Test program]1 kB

Add comment

   


Comments 

#29Kryll2022-10-13 22:39
I have a weird problem where in some email provider like outlook, the are unwanted attachments produced identical to the inline images. Any thoughts for this issue? Would love to hear a reply.
Quote
#28Dmitry2022-05-11 14:29
Incorrect code
String htmlMessage = "Hi there,";
htmlMessage += "See this cool pic: ";
htmlMessage += "";

Correct code
String htmlMessage = "Hi there,";
htmlMessage += "See this cool pic: ";
htmlMessage += "";
Quote
#27Subramanayam2021-11-14 23:36
I have tried this code. Its working fine in gmail coming to gmail image breaking and junk data coming as png in thunder bird mails. Please help me. Thanks in advance.
Quote
#26Gypsy2021-01-07 22:19
How to send an HTML code with image that bypasses the allow external image permission
Quote
#25Nagarjuna2020-05-14 07:17
How to send and read overlapping images
Quote