11

I am embedding images that have been base64 encoded in HTML as follows:

[html appendFormat:@"<html><body><p><b><img src=\"data:image/png;base64,%@\"></b></p></body><html>", base64ImageString];

I then create a new email as follows:

MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
mailVC.mailComposeDelegate = self;
[mailVC setMessageBody:html isHTML:YES];
[self presentModalViewController:mailVC animated:YES];

The embedded image does show up in the new email before it is sent, but is not displayed in any email client to which the mail is delivered. I would think the fact that the image properly shows in the draft shows that the embedding process is successful, but I dont understand why it does not show when delivered. Looking at the raw HTML in the delivered mail shows: src="cid:(null)" Any help would be appreciated please!

RunLoop
  • 20,288
  • 21
  • 96
  • 151
  • this answers code mentions that it worked apple to yahoo mail. http://stackoverflow.com/questions/1527351/how-to-add-an-uiimage-in-mailcomposer-sheet-of-mfmailcomposeviewcontroller-in-ip – Nik Burns Jan 13 '12 at 16:08
  • I'm getting the same results. That's with 5.0.1, maybe it worked before. – dwery Jan 27 '12 at 17:23
  • @dwery I am running 5.0.1 too. As an aside, pasting HTML into an email is unfortunately also broken under 5.0.1 – RunLoop Jan 29 '12 at 07:41
  • Would love any update on this problem. even non-embedded images, such as , get converted to cid and then become null for the recipient – SG1 Feb 23 '12 at 21:16
  • No luck yet I'm afraid. I do however embed linked images successfully – RunLoop Feb 24 '12 at 08:17

1 Answers1

15

I stumbled into this same problem and the solution was rather convoluted. It is possible to embed an image in an email. The problem is that for some weird reason the base64 encoded image must not contain new lines (super odd! I know). I'm guessing you are using the NSData+Base64 by Matt Gallagher? So was I! This category creates a multi-line base64 string. The code in the category is

- (NSString *)base64EncodedString
{
    size_t outputLength;
    char *outputBuffer =
        NewBase64Encode([self bytes], [self length], true, &outputLength);

    NSString *result =
        [[NSString alloc]
            initWithBytes:outputBuffer
            length:outputLength
            encoding:NSASCIIStringEncoding];
    free(outputBuffer);
    return result;
}

By replacing the third parameter of NewBase64Encode to false you will get a single line base64 string and that worked for me. I ended up creating a new function (just not to break anything else!) within the category.

- (NSString *)base64EncodedStringSingleLine
{
    size_t outputLength;
    char *outputBuffer =
    NewBase64Encode([self bytes], [self length], false, &outputLength);

    NSString *result =
    [[NSString alloc]
     initWithBytes:outputBuffer
     length:outputLength
     encoding:NSASCIIStringEncoding];
    free(outputBuffer);
    return result;
}

Using this function to encode the UIImage's NSData worked fine. The email clients I have tested so far all show the embedded image. Hope it works for you!

Edit: As pointed out in the comments, this solution is only partial. The image will be attached as a Data URI in the email. However, not all email clients will display the embedded image.

fsaint
  • 8,759
  • 3
  • 36
  • 48
  • I was very hopefully with your reply, however I've just tested on Gmail and it doesn't work.. – jcrowson May 13 '12 at 17:26
  • Yep! The image is there. However, it seems like Gmail does not supports data URIs. – fsaint May 13 '12 at 18:09
  • I had to unmark this as answered because images embedded like this do not show in outlook, although they do show in Mail on a Mac. – RunLoop May 16 '12 at 10:58
  • Ouch!!. There are compatibility issues with using data URIs with some email clients. That is, however, a problem with the technique for embedding the image and not a problem in my answer. The technique used was defined as part of the question and my answer is a correct answer to that I would say. – fsaint May 16 '12 at 13:57
  • Wonderful! Works for me. BTW Felz, you forgot an autorelease when returning result. – Ricardo May 19 '12 at 16:47
  • Ricardo you seem to be right. The thing is that the original method in the category does not release ... is that leaking!? Will check that out. – fsaint May 19 '12 at 18:51
  • Thanks a lot, works for me. It used to work with multiline back in iOS 3.1.3, but not in iOS5.1. We used it in our app. Now with the single line option it works at least for iOS/MacOSX again. – Gerd Jul 16 '12 at 15:11