0

Hey all I am trying to embed an image into my email body that will be viewed in Outlook 2016.

The problem I am coming across is if I want more than one image embedded into the body of the message then how would I do this?

I am currently creating a body message that looks like this:

< h1>I have some attachments for you. %img< /h1>

Which the %img is replaced one every loop with the image cid name ("< img src=\"cid:" + cid + "\" />")

The current code that works but with only 1 embedded image:

private static boolean createEmbeddedImg(MimeBodyPart messageBodyPart, Multipart multipart) throws MessagingException, IOException {
        int seq = 0;
        int c = (seq++) % 100000;

        String cid = c + "." + System.currentTimeMillis();

        messageBodyPart.setText(""
                  + "<html>"
                  + " <body>"
                  + "  <p>Here is my image:</p>"
                  + "  <img src=\"cid:" + cid + "\" />"
                  + " </body>"
                  + "</html>" 
                  ,"US-ASCII", "html");
        multipart.addBodyPart(messageBodyPart);

        MimeBodyPart imagePart = new MimeBodyPart();

        try {
            byte[] decodedImg = Base64.getDecoder().decode(B64.getBytes(StandardCharsets.UTF_8));
            Path destinationFile = Paths.get("c:/temp", "homer.gif");
            Files.write(destinationFile, decodedImg);
        } catch (IOException e) {
            e.printStackTrace();
             return false;
        }

        imagePart.attachFile("c:/temp/homer.gif");
        imagePart.setContentID("<" + cid + ">");
        imagePart.setDisposition(MimeBodyPart.INLINE);
        multipart.addBodyPart(imagePart);
        multipart.addBodyPart(messageBodyPart);

        return true;
    }

The code above produces an email with the embedded image and body message:

enter image description here

And this code below is what I came up with for more than just 1 embedded image in the body:

private static void _createEmbeddedImgs(MimeBodyPart messageBodyPart, Multipart multipart, String message,
        String[] embeddedImgs) throws MessagingException, IOException {
    UUID uuid = UUID.randomUUID();
    String cid = null;
    List<String> savedCIDS = new ArrayList<String>();

    if (embeddedImgs != null && embeddedImgs.length > 0) {
        for (String filePath : embeddedImgs) {
            cid = String.valueOf(uuid.variant());
            message = message.replaceFirst("%img", "<img src=\"cid:" + cid + "\" />");

            MimeBodyPart imagePart = new MimeBodyPart();

            byte[] decodedImg = Base64.getDecoder().decode(B64.getBytes(StandardCharsets.UTF_8));
            Path destinationFile = Paths.get("c:/temp", cid + ".gif");

            try {
                Files.write(destinationFile, decodedImg);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            imagePart.attachFile("c:/temp/" + cid + ".gif");
            imagePart.setContentID("<" + cid + ">");
            imagePart.setDisposition(MimeBodyPart.INLINE);
            multipart.addBodyPart(imagePart);
            savedCIDS.add(String.valueOf(cid));
        }

        messageBodyPart.setText("<html><body>" + message + "</html></body>", "US-ASCII", "html");
        multipart.addBodyPart(messageBodyPart);
    }
}

This does produce an email but it looks like this:

enter image description here

So nothing in the body at all but it did have the embedded image (2.gif)

I can not seem to graps what I am missing in order for it to work as I intended for it too.

I'm probably over-thinking this but help would be appreciated!

UPDATE

Replacing the UUID with the default random sequence produces this:

enter image description here

Reverent code changed:

int seq = 0;
        int c = (seq++) % 100000;

        String cid = c + "." + System.currentTimeMillis();

        if (embeddedImgs != null && embeddedImgs.length > 0) {
            for (String filePath : embeddedImgs) {
                message = message.replaceFirst("%img", "<img src=\"cid:" + cid + "\" />");
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
StealthRT
  • 10,108
  • 40
  • 183
  • 342
  • It's just a guess but could it be a problem of `cid` containing invalid chars? In your one-image code you have digits and a dot while in your multi-image code you use uuid which contains characters and minuses (which might be the problem). – Thomas Feb 07 '19 at 15:09
  • Btw, `String.valueOf(cid)` is superfluous since `cid` already is a string. – Thomas Feb 07 '19 at 15:11
  • @Thomas I updated my OP to show you're suggestion and it did not seem to work either. – StealthRT Feb 07 '19 at 15:15
  • Another problem might be decoding the image correctly. Did you verify that the gif works? The code you've posted suggests that `filePath` contains the base64 encoded content of the image file but you don't use that and instead have `byte[] decodedImg = Base64.getDecoder().decode(B64.getBytes(StandardCharsets.UTF_8));`. – Thomas Feb 07 '19 at 15:16

2 Answers2

0

See the JavaMail FAQ.

You want to create a multipart/related message with the text as the first part and the images as later parts.

Note that you don't need to write the image data to a file before including it in the message; see the FAQ for details.

Bill Shannon
  • 29,579
  • 6
  • 38
  • 40
0

You can insert your images directly into the HTML

    messageBodyPart.setText(""
              + "<html>"
              + " <body>"
              + "  <p>Here is my image:</p>"
              + "  <img src=\"data:image/jpg;base64," + Base64.getEncoder().encodeToString(YOUR_IMAGE_DATA) + "\" />"
              + " </body>"
              + "</html>" 
              ,"US-ASCII", "html");
    multipart.addBodyPart(messageBodyPart);

Change the mimetype of the image if you do not use JPEG.

drkunibar
  • 1,327
  • 1
  • 7
  • 7
  • Not all mail clients support `data:image/jpg` embedded images. You should only do this if you know your recipients support it. – Mark Rotteveel Feb 08 '19 at 07:30
  • @MarkRotteveel You are right. But the most populare do - see https://stackoverflow.com/questions/6070196/what-is-data-uri-support-like-in-major-email-client-software – drkunibar Feb 08 '19 at 07:39
  • IIRC, recent Outlook versions still don't support it (even though it was supported in Outlook 2003, they switched to a different render engine which doesn't), which covers a large part of businesses. – Mark Rotteveel Feb 08 '19 at 07:42