【问题标题】:Comparing Buffers比较缓冲区
【发布时间】:2020-02-14 12:11:46
【问题描述】:

我想比较内存中的两个图像,而不是依赖从文件系统读取和写入。

我可能会以错误的方式解决这个问题,如果是这样,我会很感激某种提示/帮助。

我创建了一个仓库来展示我所看到的: https://github.com/philmirez/comparing-screenshots

const puppeteer = require('puppeteer')
const pixelmatch = require('pixelmatch')
const PNG = require('pngjs').PNG
const fs = require('fs')

function getTime(startTime) {
  return Date.now() - startTime
}

async function takeScreenshot(page, options) {
  const startTime = Date.now()
  await page.goto(
    options.url,
    {
      waitUntil: 'networkidle2'
    }
  )
  const totalTime = getTime(startTime)

  await page.setViewport({
    height: options.height,
    width: options.width
  })
  const data = await page.screenshot({
    path: options.path || null,
    fullPage: true
  })

  return {
    data: data,
    time: totalTime
  }
}

async function takeScreenshots(stagingOptions, prodOptions) {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  const staging = await takeScreenshot(page, stagingOptions)
  const prod = await takeScreenshot(page, prodOptions)

  await browser.close();

  return [
    staging,
    prod
  ]
}

const run = async function () {
  try {
    const height = 900
    const width = 640
    const diff = new PNG({width, height})
    const stagingOptions = {
      path: 'stagingScreenshot.png',
      url: 'https://www.google.com/search?q=cat',
      height,
      width
    }
    const prodOptions = {
      path: 'prodScreenshot.png',
      url: 'https://www.google.com/search?q=cat',
      height,
      width
    }
    const [stagingScreenshot, prodScreenshot] = await takeScreenshots(stagingOptions, prodOptions)
    const allocationSize = height * width * 4
    const stagingBuff = Buffer.alloc(allocationSize)
    const prodBuff = Buffer.alloc(allocationSize)
    stagingBuff.fill(stagingScreenshot.data)
    prodBuff.fill(prodScreenshot.data)

    const numDiffPixels = pixelmatch(stagingBuff, prodBuff, diff.data, width, height, { threshold: 0.1 })
    fs.writeFileSync('diff.png', PNG.sync.write(diff))
    console.log('Results', JSON.stringify({
      diffScore: numDiffPixels / (height * width)
    }))
  } catch (error) {
    console.error(error)
  }
}

run()

结果差异图像看起来像红色静态。

两张图片的尺寸相同,均为 1101 x 2614。

stagingScreenshot.png:

prodScreenshot.png:

旁注:让我大吃一惊的是,当我阅读pixelmatch/index.js 文件时,它说...

if (img1.length !== width * height * 4) throw new Error('Image data size does not match width/height.')

我不明白为什么宽度和高度要乘以 4。

【问题讨论】:

  • 宽 * 高 * 4 => RGBA 数据的所有像素

标签: javascript node.js async-await puppeteer pixelmatch


【解决方案1】:

这里需要解决一些问题:

const diff = new PNG({width, height})

这是不对的,因为当您将宽度和高度发送到takeScreenshot 时,您是在使用它们来设置视口。但是当你拍摄全屏截图时,结果会比这更大。

因此,您应该根据其中一个屏幕截图创建差异。像这样的:

const [stagingScreenshot, prodScreenshot] = await takeScreenshots(stagingOptions, prodOptions)
const prodPng = PNG.sync.read(prodScreenshot.data)
const stgPng = PNG.sync.read(stagingScreenshot.data)
const diff = new PNG({width: prodPng.width, height: prodPng.height})

const numDiffPixels = pixelmatch(prodPng.data, stgPng.data, diff.data, prodPng.width, prodPng.height, { threshold: 0.1 })

【讨论】:

    【解决方案2】:

    我遇到了完全相同的错误,

    img1.length !== width * height * 4 
    

    差了十倍,所以我求助于 Jimp:https://www.npmjs.com/package/jimp

    const jimage1 = await Jimp.read(imgBuffer);
    const jimage2 = await Jimp.read(imgUrl);
    const width = jimage1.bitmap.width;
    var diff = Jimp.diff(jimage1, jimage2, .1);
    console.log("Percent Difference - ", diff.percent);
    

    它实际上是一个像素匹配的包装器

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多