带有CSS类的img的DataURL

问题描述 投票:0回答:4

由于 CSS 类,我必须在

<img>
上应用一些样式。

是否可以用CSS样式获取

dataURL
<img>

$(function() {
  // Original
  const imgOriginal = document.getElementById('original');
  const c1 = document.getElementById('c1');
  let ctx = c1.getContext('2d');
  ctx.drawImage(imgOriginal, 100, 100);

  // Filtered
  const imgFiltered = document.getElementById('filtered');
  const c2 = document.getElementById('c2');
  ctx = c2.getContext('2d');
  ctx.drawImage(imgFiltered, 100, 100);

  // Same dataURL :(
  console.log(c1.toDataURL(), c2.toDataURL());
  console.log(c1.toDataURL() === c2.toDataURL());
})
.filter::before {
  display: block;
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
  z-index: 1;
  border: 1px solid red;
}

.filter {
  position: relative;
  -webkit-filter: sepia(.5) hue-rotate(-30deg) saturate(1.4);
  filter: sepia(.5) hue-rotate(-30deg) saturate(1.4);
}

canvas {
  display: block;
  width: 100px;
  height: 100px;
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div>

  <img id="original" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg">
  <canvas id="c1"></canvas>

  <img id="filtered" class="filter" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg">
  <canvas id="c2"></canvas>

</div>

也许片段会因为

<canvas>
标签而出现错误,无论如何,这个想法是存在的。


编辑

如果有人对

SVG
或其他东西有建议,我正在使用 fabricJS


编辑2(不解决,而是寻找其他方法)

  1. 感谢@KavianK。您可以使用

    CSS
    上下文复制
    canvas
    样式,但是对我来说这很无聊,因为我们必须为每个
    callback
    类存储不同的
    CSS
    才能获得
    dataURL
    。无论如何都要工作!

  2. 感谢@Emeeus,也许您的后端提供了一个解决方案,而不是我的解决方案,因为我只想在前端执行此操作。 wkhtmltopdf

  3. 感谢@pegasuspect,我们可以用

    SVG
    过滤图像,我按照这种方式,用svgjs替换fabricJS,这个库可以轻松替换
    canvas
    ,并且使用
    更容易img
    ,我不再需要
    DataURL
    了!

  4. 感谢@Kaiido,有一种方法可以使用

    snapshot
    样式渲染的
    HTML
    CSS
    html2canvas 在这种情况下很容易获得
    dataURL
    。不幸的是,某些
    CSS
    样式尚不受支持,例如
    box-shadow
    filter
    ,这就是为什么它不是我的解决方案

这个主题尚未解决,但与

svgjs
我不需要实际与
dataURL
一起工作。

javascript html css image fabricjs
4个回答
7
投票

CSS
DOM
是与用于图像和画布的位图不同的世界。位图本身不受
CSS
的影响,仅影响充当位图镜子的元素。因此,应用于画布的 CSS 过滤器不会应用于生成的图像。您要么需要在画布中复制滤镜,要么需要将相同的滤镜重新应用到生成的图像。

示例:

上下文对象有一个鲜为人知的属性,方便地命名为 filter。这将对其本身的上下文应用过滤器。必须在下一次绘制操作之前设置过滤器。

var img = new Image();

img.crossOrigin = '';
img.src = document.getElementById( 'original' ).src;

img.onload = function() {
    var canvas = document.getElementById( 'canvas' ),
        ctx = canvas.getContext( '2d' );

    canvas.width = this.width;
    canvas.height = this.height;

    // filter
    if ( typeof ctx.filter !== 'undefined' ) {
        ctx.filter = "sepia(.5) hue-rotate(-30deg) saturate(1.4)";
        ctx.drawImage(this, 0, 0);
    } else {
        ctx.drawImage(this, 0, 0);
    }

    document.getElementById( 'filtered' ).src = canvas.toDataURL();
}
<img id="original" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg" />
<img id="filtered" />
<canvas id="canvas" style="display: none"></canvas>


2
投票

tldr;

您可以使用 SVG 来做到这一点。 http://jsfiddle.net/1hambw93/91/


如何使用SVG作为图像的数据源

这里解释得很好。它基本上表示您可以在 img

 的 src 标签中使用 svg 元素。

如何在 SVG 中使用滤镜

这里的解释也非常好:我可以使用 SVG 过滤器用您的代码实现相同的过滤效果。

您可以使用 Sepium

此站点生成 svg 过滤器,以获得与 css 相同的过滤器。到目前为止,您将拥有以下 SVG:

<svg id="test"> <image xlink:href='https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg/170px-Brad_Pitt_Inglorious_Basterds_Berlin_premiere.jpg' x="0" y="0" height="170px" width="218px" filter='url(#sepium-filter)' /> <filter id="sepium-filter"> <feColorMatrix type="matrix" values="1.3 -0.3 1.1 0 0 0 1.3 0.2 0 0 0 0 0.8 0.2 0 0 0 0 1 0"> </feColorMatrix> </filter> </svg>

然后我使用

最少的 JavaScript 代码转换为 Base64 并将 SVG 的结果写入对象,以在 HTML 中显示。


0
投票
据我了解,您需要计算的图像,因此您需要浏览器所做的工作的结果。要实现这一点,您可以专门使用

wkhtmltopdf wkhtmltoimage。它使用Qt WebKit渲染引擎(就像浏览器一样)。您必须将其安装在服务器中并运行以下命令:

wkhtmltoimage http://mysite/image-Plus-css-PLus-canvas.html myComputedImge.jpg

其中

http://mysite/image-Plus-css-PLus-canvas.html 是 html 中的图像,带有 css、javascript 等。当然,所有这些都可以使用 ajax 来完成。

因此,使用这种方式,您将获得一个

.jpg.png 文件(本例中为 myCompulatedImge.jpg),其中包含您想要计算的所有内容,例如屏幕截图。如果您想要 Base64,您可以执行与 .toDataURL()

 相同的操作,结果是图像 
with css 的 Base64。

如果您想使用 ajax 执行此操作,您可以:

    发送请求,以文件作为参数或远程 URL。
  • 如果文件是远程的,服务器必须能够访问它。
  • 在服务器端,您可以使用图像、CSS 和 JavaScript 或任何您想要的内容创建一个 .html 文件。
  • 运行上面详细的代码来创建 .jpg 或 .png
  • 响应ajax请求创建的文件的位置。
  • 在回调中,您将获得带有计算出的过滤器的新图像的 URL。
  • 既然你在服务器端有这个新图像,你可以直接响应base64而不是位置,那么在客户端你不需要
  • .toDataURL()

0
投票
有 1 个解决办法;它可能适用于您使用 CSS 的用例:

img[src^="data:image/png;"] { background-color: #000; filter: sepia(50%); }

这适用于所有以

data:image/png

 开头的图像 URL
    

© www.soinside.com 2019 - 2024. All rights reserved.