简体   繁体   English

如何在html电子邮件中嵌入图像

[英]How to embed images in html email

I'm trying to implement a code to send HTML email with embedded image.我正在尝试实现一个代码来发送带有嵌入图像的 HTML 电子邮件。

I already tried for simple HTML email with image but this image is taken from server.我已经尝试过使用带有图像的简单 HTML 电子邮件,但该图像是从服务器获取的。

I would strongly recommend using a library like PHPMailer to send emails.我强烈建议使用像PHPMailer这样的库来发送电子邮件。
It's easier and handles most of the issues automatically for you.它更容易并自动为您处理大部分问题。

Regarding displaying embedded (inline) images, here's what's on their documentation :关于显示嵌入(内联)图像,这是他们的文档中的内容

Inline Attachments内嵌附件

There is an additional way to add an attachment.还有一种添加附件的方法。 If you want to make a HTML e-mail with images incorporated into the desk, it's necessary to attach the image and then link the tag to it.如果您想制作包含桌面图像的 HTML 电子邮件,则需要附加图像,然后将标签链接到它。 For example, if you add an image as inline attachment with the CID my-photo, you would access it within the HTML e-mail with <img src="cid:my-photo" alt="my-photo" /> .例如,如果您将图像添加为 CID my-photo 的内嵌附件,您将在 HTML 电子邮件中使用<img src="cid:my-photo" alt="my-photo" />

In detail, here is the function to add an inline attachment:详细来说,这里是添加内联附件的函数:

$mail->AddEmbeddedImage(filename, cid, name);
//By using this function with this example's value above, results in this code:
$mail->AddEmbeddedImage('my-photo.jpg', 'my-photo', 'my-photo.jpg ');

To give you a more complete example of how it would work:给你一个更完整的例子来说明它是如何工作的:

<?php
require_once('../class.phpmailer.php');
$mail = new PHPMailer(true); // the true param means it will throw exceptions on     errors, which we need to catch

$mail->IsSMTP(); // telling the class to use SMTP

try {
  $mail->Host       = "mail.yourdomain.com"; // SMTP server
  $mail->Port       = 25;                    // set the SMTP port
  $mail->SetFrom('name@yourdomain.com', 'First Last');
  $mail->AddAddress('whoto@otherdomain.com', 'John Doe');
  $mail->Subject = 'PHPMailer Test';

  $mail->AddEmbeddedImage("rocks.png", "my-attach", "rocks.png");
  $mail->Body = 'Your <b>HTML</b> with an embedded Image: <img src="cid:my-attach"> Here is an image!';

  $mail->AddAttachment('something.zip'); // this is a regular attachment (Not inline)
  $mail->Send();
  echo "Message Sent OK<p></p>\n";
} catch (phpmailerException $e) {
  echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
  echo $e->getMessage(); //Boring error messages from anything else!
}
?>

Edit:编辑:

Regarding your comment, you asked how to send HTML email with embedded images, so I gave you an example of how to do that.关于您的评论,您询问了如何发送带有嵌入图像的 HTML电子邮件,所以我给了您一个如何做到这一点的示例。
The library I told you about can send emails using a lot of methods other than SMTP.我告诉过您的库可以使用 SMTP 以外的许多方法发送电子邮件。
Take a look at the PHPMailer Example page for other examples.查看PHPMailer 示例页面以获取其他示例。

One way or the other, if you don't want to send the email in the ways supported by the library, you can (should) still use the library to build the message, then you send it the way you want.一种或另一种方式,如果您不想以库支持的方式发送电子邮件,您仍然可以(应该)使用库来构建消息,然后以您想要的方式发送。

For example:例如:

You can replace the line that send the email:您可以替换发送电子邮件的行:

$mail->Send();

With this:有了这个:

$mime_message = $mail->CreateBody(); //Retrieve the message content
echo $mime_message; // Echo it to the screen or send it using whatever method you want

Hope that helps.希望有帮助。 Let me know if you run into trouble using it.如果您在使用它时遇到问题,请告诉我。

I'm using this function that find all images in my letter and attaches it to the message.我正在使用此功能在我的信件中查找所有图像并将其附加到邮件中。

Parameters: Takes your HTML (which you want to send);参数:获取您的 HTML(您要发送的内容);
Return: The necessary HTML and headers, which you can use in mail() ;返回:必要的 HTML 和标题,您可以在mail()

Example usage:用法示例:

define("DEFCALLBACKMAIL", "yourmail@yourdomain.com"); // WIll be shown as "from".
$final_msg = preparehtmlmail($html); // give a function your html*

mail('your@mail.com', 'your subject', $final_msg['multipart'], $final_msg['headers']); 
// send email with all images from html attached to letter


function preparehtmlmail($html) {

  preg_match_all('~<img.*?src=.([\/.a-z0-9:_-]+).*?>~si',$html,$matches);
  $i = 0;
  $paths = array();

  foreach ($matches[1] as $img) {
    $img_old = $img;

    if(strpos($img, "http://") == false) {
      $uri = parse_url($img);
      $paths[$i]['path'] = $_SERVER['DOCUMENT_ROOT'].$uri['path'];
      $content_id = md5($img);
      $html = str_replace($img_old,'cid:'.$content_id,$html);
      $paths[$i++]['cid'] = $content_id;
    }
  }

  $boundary = "--".md5(uniqid(time()));
  $headers .= "MIME-Version: 1.0\n";
  $headers .="Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
  $headers .= "From: ".DEFCALLBACKMAIL."\r\n";
  $multipart = '';
  $multipart .= "--$boundary\n";
  $kod = 'utf-8';
  $multipart .= "Content-Type: text/html; charset=$kod\n";
  $multipart .= "Content-Transfer-Encoding: Quot-Printed\n\n";
  $multipart .= "$html\n\n";

  foreach ($paths as $path) {
    if(file_exists($path['path']))
      $fp = fopen($path['path'],"r");
      if (!$fp)  {
        return false;
      }

    $imagetype = substr(strrchr($path['path'], '.' ),1);
    $file = fread($fp, filesize($path['path']));
    fclose($fp);

    $message_part = "";

    switch ($imagetype) {
      case 'png':
      case 'PNG':
            $message_part .= "Content-Type: image/png";
            break;
      case 'jpg':
      case 'jpeg':
      case 'JPG':
      case 'JPEG':
            $message_part .= "Content-Type: image/jpeg";
            break;
      case 'gif':
      case 'GIF':
            $message_part .= "Content-Type: image/gif";
            break;
    }

    $message_part .= "; file_name = \"$path\"\n";
    $message_part .= 'Content-ID: <'.$path['cid'].">\n";
    $message_part .= "Content-Transfer-Encoding: base64\n";
    $message_part .= "Content-Disposition: inline; filename = \"".basename($path['path'])."\"\n\n";
    $message_part .= chunk_split(base64_encode($file))."\n";
    $multipart .= "--$boundary\n".$message_part."\n";

  }

  $multipart .= "--$boundary--\n";
  return array('multipart' => $multipart, 'headers' => $headers);  
}

PHPMailer has the ability to automatically embed images from your HTML email. PHPMailer 能够从您的 HTML 电子邮件中自动嵌入图像。 You have to give full path in the file system, when writing your HTML:在编写 HTML 时,您必须在文件系统中提供完整路径:

<img src="/var/www/host/images/photo.png" alt="my photo" />

It will automaticaly convert to:它将自动转换为:

<img src="cid:photo.png" alt="my photo" />

Based on Arthur Halma's answer, I did the following that works correctly with Apple's, Android & iOS mail.根据 Arthur Halma 的回答,我做了以下与 Apple、Android 和 iOS 邮件一起正常工作的操作。

define("EMAIL_DOMAIN", "yourdomain.com");

public function send_email_html($to, $from, $subject, $html) {
  preg_match_all('~<img.*?src=.([\/.a-z0-9:_-]+).*?>~si',$html,$matches);
  $i = 0;
  $paths = array();
  foreach ($matches[1] as $img) {
    $img_old = $img;
    if(strpos($img, "http://") == false) {
      $uri = parse_url($img);
      $paths[$i]['path'] = $_SERVER['DOCUMENT_ROOT'].$uri['path'];
      $content_id = md5($img);
      $html = str_replace($img_old,'cid:'.$content_id,$html);
      $paths[$i++]['cid'] = $content_id;
    }
  }
  $uniqid   = md5(uniqid(time()));
  $boundary = "--==_mimepart_".$uniqid;

  $headers = "From: ".$from."\n".
  'Reply-to: '.$from."\n".
  'Return-Path: '.$from."\n".
  'Message-ID: <'.$uniqid.'@'.EMAIL_DOMAIN.">\n".
  'Date: '.gmdate('D, d M Y H:i:s', time())."\n".
  'Mime-Version: 1.0'."\n".
  'Content-Type: multipart/related;'."\n".
  '  boundary='.$boundary.";\n".
  '  charset=UTF-8'."\n".
  'X-Mailer: PHP/' . phpversion();

  $multipart = '';
  $multipart .= "--$boundary\n";
  $kod = 'UTF-8';
  $multipart .= "Content-Type: text/html; charset=$kod\n";
  $multipart .= "Content-Transfer-Encoding: 7-bit\n\n";
  $multipart .= "$html\n\n";
  foreach ($paths as $path) {
    if (file_exists($path['path']))
      $fp = fopen($path['path'],"r");
      if (!$fp)  {
        return false;
      }
    $imagetype = substr(strrchr($path['path'], '.' ),1);
    $file = fread($fp, filesize($path['path']));
    fclose($fp);
    $message_part = "";
    switch ($imagetype) {
      case 'png':
      case 'PNG':
            $message_part .= "Content-Type: image/png";
            break;
      case 'jpg':
      case 'jpeg':
      case 'JPG':
      case 'JPEG':
            $message_part .= "Content-Type: image/jpeg";
            break;
      case 'gif':
      case 'GIF':
            $message_part .= "Content-Type: image/gif";
            break;
    }
    $message_part .= "; file_name = \"$path\"\n";
    $message_part .= 'Content-ID: <'.$path['cid'].">\n";
    $message_part .= "Content-Transfer-Encoding: base64\n";
    $message_part .= "Content-Disposition: inline; filename = \"".basename($path['path'])."\"\n\n";
    $message_part .= chunk_split(base64_encode($file))."\n";
    $multipart .= "--$boundary\n".$message_part."\n";
  }
  $multipart .= "--$boundary--\n";
  mail($to, $subject, $multipart, $headers);
}

Here is a way to get a string variable without having to worry about the coding.这是一种无需担心编码即可获取字符串变量的方法。

If you have Mozilla Thunderbird , you can use it to fetch the html image code for you.如果您有Mozilla Thunderbird ,您可以使用它为您获取 html 图像代码。

I wrote a little tutorial here, complete with a screenshot (it's for powershell, but that doesn't matter for this):我在这里写了一个小教程,并附有屏幕截图(它用于 powershell,但这无关紧要):

powershell email with html picture showing red x 带有显示红色 x 的 html 图片的 powershell 电子邮件

And again:然后再次:

How to embed images in email 如何在电子邮件中嵌入图像

You have to encode your email as multipart mime and then you can attach emails as attachments basically.您必须将电子邮件编码为多部分 mime,然后基本上可以将电子邮件附加为附件。 You reference them by cid in the email.您在电子邮件中通过 cid 引用它们。

Alternatively you could not attach them to the email and use URLs directly but most mail programs will block this as spammers use the trick to detect the liveness of email addresses.或者,您不能将它们附加到电子邮件并直接使用 URL,但大多数邮件程序会阻止这种情况,因为垃圾邮件发送者会使用此技巧来检测电子邮件地址的活跃度。

You don't say what language but here is one example .你没有说是什么语言,但这是一个例子

This is the code I'm using to embed images into HTML mail and PDF documents.这是我用来将图像嵌入 HTML 邮件和 PDF 文档的代码。

<?php
$logo_path = 'http://localhost/img/logo.jpg';
$type = pathinfo($logo_path, PATHINFO_EXTENSION);
$image_contents = file_get_contents($logo_path);
$image64 = 'data:image/' . $type . ';base64,' . base64_encode($image_contents);

echo '<img src="' . $image64 .'" />';
?>

I made to golang command line to this job, the key part is doing cid replacement:我在 golang 命令行中做了这个工作,关键部分是做 cid 替换:

https://github.com/gonejack/embed-email https://github.com/gonejack/embed-email

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM