>웹 프론트엔드 >JS 튜토리얼 >casper.js 및 like.js를 기반으로 픽셀 비교 서비스 구현

casper.js 및 like.js를 기반으로 픽셀 비교 서비스 구현

小云云
小云云원래의
2018-01-11 09:04:051571검색

이번에는 테스터나 프런트엔드 직원이 직접 보조 테스트를 완료할 수 있도록 디자인 초안과 프런트엔드 페이지 간의 픽셀 비교를 제공하는 노드 서비스를 공유합니다. 저를 믿으십시오. 픽셀 수준의 비교를 통해 웹 페이지의 디자인 초안이 복원된 정도는 즉시 명백해집니다. 아래에서는 별로 할 말이 없지만, 자세한 소개를 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.

효과 미리보기


Pre-knowledge

이번에는 다음 두 라이브러리가 보조 도구로 사용됩니다.

  • casperjs: PhantomJS를 기반으로 작성되었습니다. 내부적으로는 인터페이스가 없는 브라우저를 제공하는데, 간단히 말해서 다양한 마우스 이벤트와 기타 여러 기능이 포함된 브라우저를 코드 형태로 시뮬레이션하는 작업을 완료하는 데 사용할 수 있습니다. 스크린샷 기능이 제공됩니다.

  • resemble.js: 이미지 픽셀 비교 도구. 호출 방법을 간단히 이해하면 두 개의 이미지가 전달되고 차이 등의 비교 매개변수와 함께 합성 이미지가 반환된다는 것입니다. 기본 구현 아이디어는 이미지를 캔버스로 변환하고 이미지 픽셀을 얻은 다음 각 픽셀을 비교하는 것으로 이해될 수 있습니다.

그래서 우리는 이미 전체 서비스에 대한 큰 아이디어를 가지고 있어야 합니다. 즉, casperjs를 사용하여 웹 사이트에 들어가 특정 페이지를 가로채고 이를 디자인 도면과 비교하여 결과를 얻는 것입니다.

전체적인 아이디어

위의 그림을 통해 대략적인 과정을 정리할 수 있을 것입니다.

  • 디자인 초안 이미지와 프론트 엔드에서 가로채야 할 웹 사이트 주소 및 노드 정보를 받습니다. page

  • 디자인 초안 저장 이미지 폴더로 이동

  • 하위 프로세스 시작, casperjs 시작, 대상 웹 사이트 차단 완료

  • 차단 후 form.html을 요청하여 이미지 주소 정보를 다시 서버로 전송

  • 서버에서 이미지를 받아 Likejs

  • 결과를 프런트엔드 페이지로 다시 전송

일부 사람들이 알아차릴 수 있는 문제가 있습니다. 정보를 casperjs에서 대상 웹사이트의 스크린샷에 직접 복사할 수 없는 이유는 무엇입니까? 서버에 다시 전달하지만 양식을 통해 정보를 제출하기 위해 양식 페이지를 열도록 선택합니까?

A: 우선 저는 casperjs와 node에 대해 잘 모릅니다. 우선 casperjs는 운영 체제에서 실행되는 노드 모듈이 아니라는 점입니다. casperjs에서 노드 서비스와 통신을 설정합니다. 방법이 있으면 알려주시기 바랍니다. 왜냐하면 저는 캐스퍼에 대해 잘 모르기 때문입니다! 둘째, 통신이 이루어지지 않기 때문에 차선책으로 캐스퍼를 통해 작성한 양식 페이지를 빠르게 열고 이미지 정보를 입력한 후 서버로 다시 전송하면 초기 요청이 완료됩니다. 따라서 .html에서 위의 작업이 있습니다.

구현 내용

간단한 정적 서버 구현

index.html 및 form.html 페이지를 반환해야 하기 때문에 초간단 정적 서버 구현이 필요합니다. 코드는 다음과 같습니다.

const MIME_TYPE = {
 "css": "text/css",
 "gif": "image/gif",
 "html": "text/html",
 "ico": "image/x-icon",
 "jpeg": "image/jpeg",
 "jpg": "image/jpg",
 "js": "text/javascript",
 "json": "application/json",
 "pdf": "application/pdf",
 "png": "image/png",
 "svg": "image/svg+xml",
 "swf": "application/x-shockwave-flash",
 "tiff": "image/tiff",
 "txt": "text/plain",
 "wav": "audio/x-wav",
 "wma": "audio/x-ms-wma",
 "wmv": "video/x-ms-wmv",
 "xml": "text/xml"
}
function sendFile(filePath, res) {
 fs.open(filePath, 'r+', function(err){ //根据路径打开文件
  if(err){
   send404(res)
  }else{
   let ext = path.extname(filePath)
   ext = ext ? ext.slice(1) : 'unknown'
   let contentType = MIME_TYPE[ext] || "text/plain" //匹配文件类型
   fs.readFile(filePath,function(err,data){
    if(err){
     send500(res)
    }else{
     res.writeHead(200,{'content-type':contentType})
     res.end(data)
    }
   })
  }
 })
}

양식을 구문 분석하고 이미지 폴더에 이미지를 저장합니다

const multiparty = require('multiparty') //解析表单
let form = new multiparty.Form()
 form.parse(req, function (err, fields, files) {
  let filename = files['file'][0].originalFilename,
   targetPath = __dirname + '/images/' + filename,
  if(filename){
   fs.createReadStream(files['file'][0].path).pipe(fs.createWriteStream(targetPath))
   ...
  } 
 })

읽을 수 있는 스트림을 생성하여 파일 내용을 읽은 다음 파이프를 통해 지정된 경로에 작성하여 업로드된 이미지를 저장합니다.

Run casperjs

const { spawn } = require('child_process')
spawn('casperjs', ['casper.js', filename, captureUrl, selector, id])
casperjs.stdout.on('data', (data) => {
 ...
})

spawn을 통해 casperjs를 시작하는 하위 프로세스를 만들 수 있고 exec 등을 사용할 수도 있습니다.

스크린샷을 찍어 form.html

const system = require('system')
const host = 'http://10.2.45.110:3033'
const casper = require('casper').create({
 // 浏览器窗口大小
 viewportSize: {
  width: 1920,
  height: 4080
 }
})
const fileName = decodeURIComponent(system.args[4])
const url = decodeURIComponent(system.args[5])
const selector = decodeURIComponent(system.args[6])
const id = decodeURIComponent(system.args[7])
const time = new Date().getTime()
casper.start(url)
casper.then(function() {
  console.log('正在截图请稍后')
  this.captureSelector('./images/casper'+ id + time +'.png', selector)
})
casper.then(function() {
 casper.start(host + '/form.html', function() {
  this.fill('form#contact-form', {
   'diff': './images/casper'+ id + time +'.png',
   'point': './images/' + fileName,
   'id': id
  }, true)
 })
})
casper.run()

에 데이터를 제출하세요. 코드는 비교적 간단합니다. 주요 프로세스는 페이지를 연 다음 작업을 전달하고 마지막으로 실행을 실행하는 것입니다. 이 과정에서 노드 서비스와 통신하는 방법을 잘 몰라서 다른 페이지를 열기로 했습니다. . 더 깊이 있게 공부하고 싶다면 casperjs 공식 웹사이트를 방문해보세요. 매우 자세하게 설명되어 있습니다!

like.js를 통해 픽셀 비교 및 ​​반환 데이터 수행

function complete(data) {
  let imgName = 'diff'+ new Date().getTime() +'.png',
   imgUrl,
   analysisTime = data.analysisTime,
   misMatchPercentage = data.misMatchPercentage,
   resultUrl = './images/' + imgName
  fs.writeFileSync(resultUrl, data.getBuffer())
  imgObj = {
   ...
  }
  let resEnd = resObj[id] // 找回最开始的res返回给页面数据
  resEnd.writeHead(200, {'Content-type':'application/json'})
  resEnd.end(JSON.stringify(imgObj))
 }
let result = resemble(diff).compareTo(point).ignoreColors().onComplete(complete)

여기에는 요점이 포함됩니다. 즉, 지금 얻은 결과는 원래 요청으로 반환되어야 하며 초기 요청부터 지금까지 여러 전송되었습니다. 이제 원래 반환 본문 res를 찾을 수 없습니다. 한참 고민한 끝에 전역 객체를 임시로 설정할 수 밖에 없더군요. 초기 요청을 받은 후 요청자의 IP와 타임스탬프를 고유한 ID로 설정하여 객체의 키로 저장하면 그 값이 현재 값이 됩니다. 입술. 동시에 전체 전송 과정에서 항상 id가 전달되며, 마지막으로 resObj[id]를 호출하여 초기 반환 본문과 데이터를 가져옵니다. 이 방법이 최적의 솔루션은 아니라고 생각하지만, 현재는 좋은 방법이 생각나지 않아서 전체 서비스를 실행하려면 이 방법을 해야만 합니다. . 새로운 아이디어가 있으면 알려주세요! !

Deployment

PhantomJS(osx) 설치

공식 다운로드: phantomjs-2.1.1-macosx.zip

압축 해제 경로: /User/xxx/phantomjs-2.1.1-macosx

환경 변수 추가: ~ /.bash_profile 파일에

export PATH="$PATH:/Users/xxx/phantomjs-2.1.1-macosx/bin"을 추가하세요

터미널 입력: phantomjs --version

버전 번호가 보이면, 설치가 성공적이었습니다

Casperjs 설치

brew update && brew install casperjs

like.js 설치

cnpm i resemblejs //已写进packjson可不用安装
brew install pkg-config cairo libpng jpeg giflib
cnpm i canvas //node内运行canvas

node service

git clone https://github.com/Aaaaaaaty/gui-auto-test.git
cd gui-auto-test
cnpm i
cd pxdiff
nodemon server.js

http://localhost:3033/index.html

열기 관련 권장 사항:

모바일 개발 튜토리얼의 픽셀 표시 문제 요약_경험 및 팁_웹 페이지 제작

0.5픽셀 테두리를 달성하기 위한 CSS용 샘플 코드

해상도, 픽셀 및 PPI에 대한 자세한 소개

위 내용은 casper.js 및 like.js를 기반으로 픽셀 비교 서비스 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.