【问题标题】:Insert route of image of Android in HTML with Flutter [closed]使用 Flutter 在 HTML 中插入 Android 图像的路由 [关闭]
【发布时间】:2021-02-10 21:50:39
【问题描述】:

我在一个 android 应用程序中使用 mailer2 包进行颤振,我用它发送电子邮件。在这些电子邮件中,我有一个模板,我想在其中上传图像文件,但我不知道如何。

我要上传的图片在 Android 设备的内部存储中,所以我尝试使用此路径将图片加载到 HTML 中,但它没有加载。

  <img src="/storage/emulated/0/DCIM/Camera/20210205_155258.jpg" alt="MyImages">

我需要知道如何在 Android 中将图像的内部路径加载到 &lt;img src=" ruta-IMG"&gt;,以便我的 HTML 模板可以工作。

我在 Dart Flutter 中发送电子邮件的功能如下

 sendMail() async {
String mensaje='';
var options = new GmailSmtpOptions()
  ..username = 'xxxxxxxxxxxxxxx@gmail.com'
  ..password = 'xxxxxxxxxxxxxxxxxxxxxx';

var emailTransport = new SmtpTransport(options);

var envelope = new Envelope()
  ..from = 'xxxxxxxxx@gmail.com'
  ..recipients.add('xxxxxxxxxxxxx@gmail.com')
  ..bccRecipients.add('xxxxxxxxxxxxxx@gmail.com')
  ..subject = ' images'
  ..text = 'This is a  email message.'
  ..html = ''' [ HTML IMAGES] ''';

  await
emailTransport
    .send(envelope)
    .then((envelope) => mensaje = 'Email sent!')
    .catchError((e) => mensaje = 'Error occurred: $e');
return mensaje;

}

显示 [HTML IMAGES] 的 html 变量转到以下 HTML 模板,这是我遇到的错误。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Images</title>
    <!--[if (mso 16)]>
    <style type="text/css">
    a {text-decoration: none;}
    </style>
    <![endif]-->
  <!--[if gte mso 9]><style>sup { font-size: 100% !important; }</style><![endif]-->
  <style type="text/css">
    @media only screen and (max-width:600px) {
      p,
      ul li,
      ol li,
      a {
        font-size: 16px!important
      }
      h1 {
        font-size: 30px!important;
        text-align: center
      }
      h2 {
        font-size: 26px!important;
        text-align: center
      }
      h3 {
        font-size: 20px!important;
        text-align: center
      }
      h1 a {
        font-size: 30px!important
      }
      h2 a {
        font-size: 26px!important
      }
      h3 a {
        font-size: 20px!important
      }
      .es-menu td a {
        font-size: 16px!important
      }
      .es-header-body p,
      .es-header-body ul li,
      .es-header-body ol li,
      .es-header-body a {
        font-size: 16px!important
      }
      .es-footer-body p,
      .es-footer-body ul li,
      .es-footer-body ol li,
      .es-footer-body a {
        font-size: 16px!important
      }
      .es-infoblock p,
      .es-infoblock ul li,
      .es-infoblock ol li,
      .es-infoblock a {
        font-size: 12px!important
      }
      *[class="gmail-fix"] {
        display: none!important
      }
      .es-m-txt-c,
      .es-m-txt-c h1,
      .es-m-txt-c h2,
      .es-m-txt-c h3 {
        text-align: center!important
      }
      .es-m-txt-r,
      .es-m-txt-r h1,
      .es-m-txt-r h2,
      .es-m-txt-r h3 {
        text-align: right!important
      }
      .es-m-txt-l,
      .es-m-txt-l h1,
      .es-m-txt-l h2,
      .es-m-txt-l h3 {
        text-align: left!important
      }
      .es-m-txt-r img,
      .es-m-txt-c img,
      .es-m-txt-l img {
        display: inline!important
      }
      .es-button-border {
        display: block!important
      }
      .es-button {
        font-size: 20px!important;
        display: block!important;
        border-width: 10px 0px 10px 0px!important
      }
      .es-btn-fw {
        border-width: 10px 0px!important;
        text-align: center!important
      }
      .es-adaptive table,
      .es-btn-fw,
      .es-btn-fw-brdr,
      .es-left,
      .es-right {
        width: 100%!important
      }
      .es-content table,
      .es-header table,
      .es-footer table,
      .es-content,
      .es-footer,
      .es-header {
        width: 100%!important;
        max-width: 600px!important
      }
      .es-adapt-td {
        display: block!important;
        width: 100%!important
      }
      .adapt-img {
        width: 100%!important;
        height: auto!important
      }
      .es-m-p0 {
        padding: 0px!important
      }
      .es-m-p0r {
        padding-right: 0px!important
      }
      .es-m-p0l {
        padding-left: 0px!important
      }
      .es-m-p0t {
        padding-top: 0px!important
      }
      .es-m-p0b {
        padding-bottom: 0!important
      }
      .es-m-p20b {
        padding-bottom: 20px!important
      }
      .es-mobile-hidden,
      .es-hidden {
        display: none!important
      }
      .es-desk-hidden {
        display: table-row!important;
        width: auto!important;
        overflow: visible!important;
        float: none!important;
        max-height: inherit!important;
        line-height: inherit!important
      }
      .es-desk-menu-hidden {
        display: table-cell!important
      }
      table.es-table-not-adapt,
      .esd-block-html table {
        width: auto!important
      }
      table.es-social {
        display: inline-block!important
      }
      table.es-social td {
        display: inline-block!important
      }
    }
    
    #outlook a {
      padding: 0;
    }
    
    .ExternalClass {
      width: 100%;
    }
    
    .ExternalClass,
    .ExternalClass p,
    .ExternalClass span,
    .ExternalClass font,
    .ExternalClass td,
    .ExternalClass div {
      line-height: 100%;
    }
    
    .es-button {
      mso-style-priority: 100!important;
      text-decoration: none!important;
    }
    
    a[x-apple-data-detectors] {
      color: inherit!important;
      text-decoration: none!important;
      font-size: inherit!important;
      font-family: inherit!important;
      font-weight: inherit!important;
      line-height: inherit!important;
    }
    
    .es-desk-hidden {
      display: none;
      float: left;
      overflow: hidden;
      width: 0;
      max-height: 0;
      line-height: 0;
      mso-hide: all;
    }
  </style>
</head>
<body>
    <table cellpadding="0" cellspacing="0" class="es-right" align="right" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;float:right;">
        <tr style="border-collapse:collapse;">
            <td width="270" align="left" style="padding:0;Margin:0;">
                <table cellpadding="0" cellspacing="0" width="100%" style="mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;border-spacing:0px;">
                    <tr style="border-collapse:collapse;">
                    </tr>
                    <tr style="border-collapse:collapse;">
                        <td align="center" style="padding:0;Margin:0;padding-top:10px;">
                            <h3 style="Margin:0;line-height:120%;mso-line-height-rule:exactly;font-family:arial, 'helvetica neue', helvetica, sans-serif;font-size:20px;font-style:normal;font-weight:normal;color:#333333;">Image Title Goes Here</h3>
                            <!--PROBLEM WITH IMAGE PATH--><img src="/storage/emulated/0/DCIM/Camera/20210205_155258.jpg" alt="MyImages"><!--PROBLEM WITH IMAGE PATH-->
                        </td>
                    </tr>
                    <tr style="border-collapse:collapse;">
                        <td align="left" style="padding:0;Margin:0;padding-top:5px;">
                            <p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-size:14px;font-family:arial, 'helvetica neue', helvetica, sans-serif;line-height:150%;color:#333333;">You can change the size, layout or link of the downloaded image in the left-hand side menu.</p>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
    
</body>
</html>

问题出现在 HTML 模板中,这是我需要从内部 Android 存储调用的文件的路径...标记为 &lt;! - PROBLEM WITH THE IMAGE PATH -&gt;

这对我有用,但我需要将 URL 更改为本地路径,但我不知道该怎么做。我展示了与 url 一起使用的图像。 Img with URL

将 URL 更改为 Local 的路径是 -> /storage/emulated/0/DCIM/Camera/20210205_155258.jpg,这条路我需要..

【问题讨论】:

  • 您使用哪个应用程序来显示 html?您要发送 html 电子邮件吗?
  • @blackapps- 我更改了帖子以更好地理解 元素路径的错误
  • @Nautilus 您是否尝试过读取图像并将其转换为 base64 字符串?它看起来像这样&lt;img src="data:image/png;base64,......." &gt;
  • @Nautilus 您可以将其附加到您的 HTML 字符串中。样品&lt;image src="$encodedImage"&gt;。请尝试使用 bezkoder.com/dart-base64-image 将您的图像编码为 base64。
  • 我投票结束这个问题,因为标题不是英文的

标签: android html flutter dart


【解决方案1】:

这是使用 CID 附件嵌入图像的示例代码。

main.dart

import 'package:flutter/material.dart';
import 'package:mailer2/mailer.dart';
import 'package:sample/my_envelope.dart';

void main() {
  runApp(MaterialApp(
    home: Home(),
  ));
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final SmtpOptions options = GmailSmtpOptions()
      ..username = '<<<<<<<<<<<<<<<<<<<< YOUR EMAIL >>>>>>>>>>>>>>>>>>>>>>>>'
      ..password = '<<<<<<<<<<<<<<<<<<<< YOUR PASSWORD >>>>>>>>>>>>>>>>>>>>>>>>';
    final SmtpTransport emailTransport = SmtpTransport(options);
    final List<CIDEmbed> cidEmbeds = <CIDEmbed>[
      const CIDEmbed(
        cid: 'cloud',
        filename: 'cloud.png',
        mimeType: 'image/png',
        base64Data:
            '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',
      ),
    ];

    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: TextButton(
          onPressed: () {
            final MyEnvelope envelope = MyEnvelope(cidEmbeds: cidEmbeds)
              ..from = 'foo@bar.com'
              ..recipients.add('<<<<<<<<<<<<<<<<<<<<<<<< DESTINATION EMAIL >>>>>>>>>>>>>>>>>>>')
              ..subject = 'Testing the Dart Mailer library'
              ..text = 'This is a cool email message. Whats up?'
              ..html =
                  '<h1>Test</h1><p>Hey!</p><img src="cid:cloud" alt="MyImages" />';

            emailTransport
                .send(envelope)
                .then((envelope) => print('Email sent!'))
                .catchError((e) => print('Error occurred: $e'));
          },
          child: const Text('SEND'),
        ),
      ),
    );
  }
}

my_envelope.dart

import 'package:flutter/material.dart';
import 'package:mailer2/mailer.dart';

class MyEnvelope extends Envelope {
  MyEnvelope({this.cidEmbeds});

  final List<CIDEmbed> cidEmbeds;

  @override
  Future<String> getContents() async {
    final String contents = await super.getContents();

    if (cidEmbeds == null || cidEmbeds.isEmpty) {
      return contents;
    }

    final StringBuffer buffer = StringBuffer();
    final int start = contents.lastIndexOf('--$identityString');
    final int end = contents.lastIndexOf('--');
    final String boundary = contents.substring(start, end);

    for (final CIDEmbed cidEmbed in cidEmbeds) {
      buffer.write('\r\n\r\n');
      buffer.write('$boundary\r\n');
      buffer.write(
          'Content-Type: ${cidEmbed.mimeType}; name="${cidEmbed.filename}"\r\n');
      buffer.write('Content-Transfer-Encoding: base64\r\n');
      buffer.write('Content-ID: <${cidEmbed.cid}>\r\n');
      buffer.write(
          'Content-Disposition: inline; filename="${cidEmbed.filename}"\r\n');
      buffer.write(cidEmbed.base64Data);
    }

    buffer.write('\r\n\r\n--$boundary--\r\n\r\n.');
    return contents.replaceRange(start, contents.length, buffer.toString());
  }
}

///
///
///
class CIDEmbed {
  const CIDEmbed({
    @required this.cid,
    @required this.filename,
    @required this.mimeType,
    @required this.base64Data,
  });

  final String cid;
  final String filename;
  final String mimeType;
  final String base64Data;
}

【讨论】:

  • 结果成功了,非常感谢您的帮助,对于延迟回复感到抱歉。它也适用于 PDF 文档吗?如果我将 更改为
  • @Nautilus 我还没有尝试过 PDF。您可以尝试使用 PDF 是否有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-05
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-26
相关资源
最近更新 更多