Reputation: 342
I'm trying to send email from javamail with embeded base64 image (img alt='image PNG' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...AElFTkSuQmCC'")
It's working with small image but when images are bigger the image doesnt show in lotus note.
Here a part of the code
Transport transport = mailSession.getTransport();
MimeMessage message = new MimeMessage( mailSession );
message.setSubject( subject );
message.setFrom( new InternetAddress( me) );
message.setContent( bodyWithEmbeddedBase64Image, "text/html" );
transport.connect();
transport.sendMessage( message, message.getAllRecipients() );
transport.close();`
I would like to use PreencodedMimeBodyPart to test it but I don't know how to use it Can someone help me please :) ?
Upvotes: 6
Views: 8497
Reputation: 2922
Try Below!
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.imageio.ImageIO;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
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.MimeMultipart;
private File getImgFile(String data, String cid) throws IOException {
String base64Image = data.split(",")[1];
byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));
File outputfile = new File(cid);
ImageIO.write(img, "jpg", outputfile);
return outputfile;
}
public Message buildMessageWithEmbeddedImage(Session session) throws MessagingException, IOException {
SMTPMessage m = new SMTPMessage(session);
MimeMultipart content = new MimeMultipart("related");
MimeBodyPart textPart = new MimeBodyPart();
String html = "HTML"; //Your HTML having Base64 Encoded Images
String[] parts = html.split("src=\"");
Map<String, File> map = new HashMap<>();
String revisedHTML = parts[0];
for(int i=1; i<parts.length; i++) {
String img = parts[i].substring(0, parts[i].indexOf("\""));
String cid = ContentIdGenerator.getContentId();
File f = getImgFile(img, cid);
map.put(cid, f);
revisedHTML+= "src=\"cid:"+cid+"\" "+parts[i].substring(parts[i].indexOf("\""), parts[i].length());
}
textPart.setText(revisedHTML, "US-ASCII", "html");
content.addBodyPart(textPart);
for (String k : map.keySet()) {
// Image part
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.attachFile(map.get(k));
imagePart.setContentID("<" + k + ">");
imagePart.setDisposition(MimeBodyPart.INLINE);
content.addBodyPart(imagePart);
}
m.setContent(content);
m.setSubject("Your Email Subject");
return m;
}
Note: Image files will be created on your project root folder you can delete if you want to delete after sending email. But make sure delete after email sent.
Upvotes: 0
Reputation: 342
Ok guys I found my answers, I don't know if I'm doing right, but is working.
Here my code :
private static final Pattern imgRegExp = Pattern.compile( "<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>" );
public send(email) throws Exception{
Map<String, String> inlineImage = new HashMap<String, String>();
String body = email.getBody();
final Matcher matcher = imgRegExp.matcher( body );
int i = 0;
while ( matcher.find() ) {
String src = matcher.group();
if ( body.indexOf( src ) != -1 ) {
String srcToken = "src=\"";
int x = src.indexOf( srcToken );
int y = src.indexOf( "\"", x + srcToken.length() );
String srcText = src.substring( x + srcToken.length(), y );
String cid = "image" + i;
String newSrc = src.replace( srcText, "cid:" + cid );
inlineImage.put( cid, srcText.split( "," )[1] );
body = body.replace( src, newSrc );
i++;
}
}
Transport transport = mailSession.getTransport();
MimeMessage message = new MimeMessage( mailSession );
message.setSubject( email.getObjet() );
message.setSender( new InternetAddress( email.getSender() ) );
message.setFrom( new InternetAddress( email.getFrom()) );
BodyPart bp = new MimeBodyPart();
bp.setContent( body, "text/html" );
MimeMultipart mmp = new MimeMultipart();
mmp.addBodyPart( bp );
Iterator<Entry<String, String>> it = inlineImage.entrySet().iterator();
while ( it.hasNext() ) {
Entry<String, String> pairs = it.next();
PreencodedMimeBodyPart pmp = new PreencodedMimeBodyPart( "base64" );
pmp.setHeader( "Content-ID", "<" + pairs.getKey() + ">" );
pmp.setDisposition( MimeBodyPart.INLINE );
pmp.setText( pairs.getValue() );
mmp.addBodyPart( pmp );
}
message.setContent( mmp );
message.addRecipient( Message.RecipientType.TO, new InternetAddress( email.getTo() ) );
transport.connect();
transport.sendMessage( message, message.getAllRecipients() );
transport.close();
}
Thanks to help me to improve if it need to be improved :)
Upvotes: 9
Reputation: 29971
Since the image isn't in a separate body part, PreencodedMimeBodyPart won't help you.
How are you base64 encoding the image?
An alternative is to use a multipart/related message, with the image in a separate part, referenced using a cid: URL.
Upvotes: 1