How to add a image in email body using MFMailComposeViewController
Asked Answered
M

4

26

I am trying to find out the best way to add an image inside the body of the email and not as attachment in ios.

1) Apple has provided a function "addAttachment" and the doc says, to add any image in the content, we should use this function, but I tried that function, and sent an mail, I checked on my browser, it is recieved as an attachment.

2) Secondly, many blogs say to use base64 encoding, but that also wont work, image is sent as a broken one.

So friends, please help me out to find the best available solution to do this.

Regards Ranjit

Macrogamete answered 31/8, 2012 at 7:16 Comment(1)
Detailed answer is hereNena
D
62

Set email format as HTML. This code is woking fine in my app.

MFMailComposeViewController *emailDialog = [[MFMailComposeViewController alloc] init];

NSString *htmlMsg = @"<html><body><p>This is your message</p></body></html>";

NSData *jpegData = UIImageJPEGRepresentation(emailImage, 1.0);

NSString *fileName = @"test";
fileName = [fileName stringByAppendingPathExtension:@"jpeg"];
[emailDialog addAttachmentData:jpegData mimeType:@"image/jpeg" fileName:fileName];

emailDialog setSubject:@"email subject"];
[emailDialog setMessageBody:htmlMsg isHTML:YES];


[self presentModalViewController:emailDialog animated:YES];
[emailDialog release];

Swift 5

import MessageUI

    func composeMail() {

        let mailComposeVC = MFMailComposeViewController()

        mailComposeVC.addAttachmentData(UIImage(named: "emailImage")!.jpegData(compressionQuality: CGFloat(1.0))!, mimeType: "image/jpeg", fileName:  "test.jpeg")

        mailComposeVC.setSubject("Email Subject")

        mailComposeVC.setMessageBody("<html><body><p>This is your message</p></body></html>", isHTML: true)

        self.present(mailComposeVC, animated: true, completion: nil)
    }
Denizen answered 31/8, 2012 at 7:24 Comment(10)
Hi @MSK , thanks for ur reply, have you checked the received mail in browser, eg, for gmail , yahoo, how does it appear, inside the body of the email or as a attchment?Macrogamete
Hi @MSK, I have a doubt, here only u have created the string using HTML and not Image, so how is that going into the body, and suppose if I not create the string using HTML then the image goes as attachment,not very clear to me, could you please explainMacrogamete
Hi @MSK, could u please look at my doubtMacrogamete
@Macrogamete I am not sure but most likely it is MFMailComposeViewController sending them inline if mail format is HTML (and the content).Denizen
I thought so, but thats strange, and what role the filename plays?Macrogamete
Filename parameter must not be nil. If you open mail in Mail App on OS X and save the image to disk, the file name is retained.Denizen
Anyone worked out a Swift equivalent? This approach is not working for me in Swift.Patrizius
This solution does NOT work to insert an image in the message BODY as OP requested. See the below solution by @Richard for Swift or mine below that in Obj-C.Sententious
@Sententious try opening the mail in Gmail, Yahoo clients (web, iOS, Android). My experience was that the base 64 encoded embedded image was not rendered in some email clients. Finally we uploaded and used the hosted image in HTML email.Denizen
The thing is that code provided does not include an image in the email body. The image body is defined as HTML yet the HTML does make reference to the image. So while some mail clients might choose to inline the image attachment entirely on their own, it was not technically in the body of the message.Sententious
S
11

I just went through this recently for Swift.

Function to add photo to email in Swift:

func postEmail() {
    var mail:MFMailComposeViewController = MFMailComposeViewController()
    mail.mailComposeDelegate = self
    mail.setSubject("your subject here")

    var image = // your image here
    var imageString = returnEmailStringBase64EncodedImage(image)
    var emailBody = "<img src='data:image/png;base64,\(imageString)' width='\(image.size.width)' height='\(image.size.height)'>"

    mail.setMessageBody(emailBody, isHTML:true)

    self.presentViewController(mail, animated: true, completion:nil)
}

Function to return the formatted image:

func returnEmailStringBase64EncodedImage(image:UIImage) -> String {
    let imgData:NSData = UIImagePNGRepresentation(image)!;
    let dataString = imgData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
    return dataString
}
Sabian answered 20/11, 2014 at 19:24 Comment(4)
Do these images show up for you correctly in Gmail, Hotmail, etc.? They aren't for me..Vanscoy
@Richard, superb solution :-D.Victualler
This works in iOS, but beware - still does not work in hotmail, gmail or for that matter most other clients as egfconnor mentioned.Irwinirwinn
@Sabian this does not actually work. Picture gets blown up massively and receiver gets image's encoding instead of the picture itself if they use GMail's web client (or others, as egfconnor pointed out).Hymie
S
3

I've found that (at least in my case) a PNG will work in the message composer but NOT when the message is opened / received by the user.

Composer Dandily showing logo PNG image!

Viewer Not so much logo images over here.

(Occasionally there will be a light blue outline where the image should be.)

Using the HTML body string below and the conversion below that seems to do the trick.


Message Body HTML String using JPEG

NSString *body = [NSString stringWithFormat:
                  @"\
                  <html>\
                    <body>\
                        Check out the App!\
                        <br>\
                        Isn't this a terriffic logo?!.\
                        <br>\
                        <img src = \"data:image/jpeg;base64,%@\" width = 100 height= 100>\
                        <br>\
                        <a href = \"%@\" > CLICK ITTTTTTT! </a>\
                    </body>\
                  </html>",
                  imageString, @"http://www.LOLamazingappLOL.com"];

Convert Image to string with JPEG Data

+ (NSString *)dataStringFromImage:(UIImage *)image
{
    NSData *imgData = UIImageJPEGRepresentation(image, 1);
    return [imgData base64EncodedStringWithOptions:kNilOptions];
}

Additional Info:

  • iOS Target = 8.0
  • iOS Device = 9.1
  • I am awful with HTML!

Thank you @Richard for the CORRECT answer to this question.

Sententious answered 2/11, 2015 at 10:8 Comment(1)
No, this doesn't work, the image doesn't show in the received email.Ticknor
M
1

Few things to note: - Use addAttachmentData - use setMessageBody and set isHTML:true

you dont have to add manually in your email body. the api will take care of that.

func postEmail() {
var mail:MFMailComposeViewController = MFMailComposeViewController()
mail.mailComposeDelegate = self
mail.setSubject("your subject here")
var image = // your image here
var imageData = UIImageJPEGRepresentation(image, 1)
mail.addAttachmentData(imageData, mimeType:"image/jpeg", fileName:"Your Filename"
var emailBody = "<html><body><p>This is your message</p></body></html>"
mail.setMessageBody(emailBody, isHTML:true)

self.presentViewController(mail, animated: true, completion:nil)}
Messieurs answered 3/10, 2016 at 6:18 Comment(1)
but the images are not inside the mail bodyStanza

© 2022 - 2024 — McMap. All rights reserved.