首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用p5.js导入gif保存画布?

如何用p5.js导入gif保存画布?
EN

Stack Overflow用户
提问于 2021-03-15 23:13:47
回答 1查看 449关注 0票数 3

我在画布上创建一个gif

代码语言:javascript
运行
复制
function preload() {
  gif = createImg("GIFS/" + gifId + ".gif");
  gif.position(random(-300, 1600), random(-300, 1000));
  gif.size(w, w);
}

我在努力拯救画布:

代码语言:javascript
运行
复制
function mousePressed() {
  saveFrames("out", "png", 1, 25);
}

为什么saveFrames不使用gif保存画布?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-16 01:08:41

createImg()只创建<img />元素,该元素被添加到DOM中。

如果希望被saveFrames捕获,则需要将其呈现给p5.js <canvas />

实现这一目标的一种方法是使用drawingContext调用drawImage(),它应该将<img />内容绘制到p5.js的画布中。

如果是这样:

代码语言:javascript
运行
复制
function preload() {
  gif = createImg("GIFS/" + gifId + ".gif");
}
function setup(){
  drawingContext.drawImage(gif.elt, random(-300, 1600), random(-300, 1000), w, w);
}

注意,代码没有经过测试,但希望能说明这个想法。如果gif没有在setup()中完全加载,您可能需要在加载回调中这样做。此外,如果gif是动画,则可能需要根据gif框架多次呈现。

下面是一个基本的演示:

代码语言:javascript
运行
复制
// load and display an HTML <img /> element in p5.js' canvas
let imgElement;

function setup() {
  createCanvas(400, 400);
  imgElement = createImg(
    'https://p5js.org/assets/img/asterisk-01.png',
    'the p5 magenta asterisk'
  );
  // hide <img /> element
  imgElement.hide();
}

// render <img /> into p5.js canvas
function renderImg(anyImg, x, y, w, h){
  drawingContext.drawImage(anyImg.elt, x, y, w, h);
}

function draw(){
  let imgSize = random(24, 144);
  renderImg(imgElement, random(-144, width), random(-144, height), imgSize, imgSize);
}

function keyPressed(){
  if(key == 's' || key == 'S'){
    saveFrames("out", "png", 1, 15);
    console.log("saving frames -> test on a local webserver");
  }
}
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.0/p5.min.js"></script>

请注意,在上面的演示中,saveFrames()不能工作:您需要使用本地won服务器。

另外,如果需要记录超过15帧,可以使用ccapture.js库(如p5.js引用所示)。

对于进一步的gif操作,更新您可能需要一个js库来解码gif文件。外面可能有很多人。下面是一个使用吉弗勒在p5.js画布中呈现的基本示例

代码语言:javascript
运行
复制
var frames = 0;
var p5Canvas;
function setup(){
  p5Canvas = createCanvas(600, 600);
  
  // Load the GIF, set custom frame render function 
  gifler('http://themadcreator.github.io/gifler/assets/gif/run.gif').frames(p5Canvas.elt, onDrawFrame);
  
}
function onDrawFrame(ctx, frame) {
  // Match width/height to remove distortion
  ctx.canvas.width  = ctx.canvas.offsetWidth;
  ctx.canvas.height = ctx.canvas.offsetHeight;

  // Determine how many pikachus will fit on screen
  var n = Math.floor((ctx.canvas.width)/150)
  for(var x = 0; x < n; x++) {
    // Draw a pikachu
    var left = x * 150;
    ctx.globalCompositeOperation = 'source-over';
    ctx.drawImage(frame.buffer, frame.x + left, frame.y, 150, 100);

    // Composite a color
    var hue = (frames * 10 + x * 50) % 360;
    ctx.globalCompositeOperation = 'source-atop';
    ctx.fillStyle = 'hsla(' + hue + ', 100%, 50%, 0.5)';
    ctx.fillRect(left, 0, 150, this.height);
  }
  frames++;
}
代码语言:javascript
运行
复制
<script src="http://themadcreator.github.io/gifler/assets/gifler.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.0/p5.min.js"></script>

代码语言:javascript
运行
复制
var gifFrames;
var offscreenCanvas;

function setup(){
  // make an offscreen canvas (of gif dimensions) to render the gif into
  offscreenCanvas = createElement('canvas');
  // hide offscreen canvas
  offscreenCanvas.hide();
  // main p5 canvas to use
  createCanvas(600, 600);
  
  // Load the GIF, set custom frame render function 
  gifler('http://themadcreator.github.io/gifler/assets/gif/run.gif').animate(offscreenCanvas.elt).then( function(result){
  // extract canvas element of each frame
  gifFrames = result._frames;
} );
  
}

function draw(){
  // if the gif frames are ready
  if(gifFrames){
    // pick a frame
    let gifFrame = gifFrames[frameCount % gifFrames.length];
    // if the canvas of the frame is ready to be accessed
    if(gifFrame.buffer){
      // render the frame at random positions and sizes
      let randomSize = random(32, 192);
      drawingContext.drawImage(gifFrame.buffer, random(-192, width), random(-192, height), randomSize, randomSize);
    }
  }
}
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.0/p5.min.js"></script>
<script src="http://themadcreator.github.io/gifler/assets/gifler.js"></script>

getCurrentFrame()/numFrames()/setFrame()/reset()/play()/pause()/delay())更新原来p5.Image已经提供了gif支持,包括帧的控制(例如,p5.Image)

这使它变得更容易,并且不需要其他js库:

代码语言:javascript
运行
复制
let randomLocations = [];
let gif;

function preload(){
  gif = loadImage("http://themadcreator.github.io/gifler/assets/gif/run.gif");
}

function setup(){
  createCanvas(600, 600);
  mousePressed();
}

function mousePressed(){
  randomLocations.push(createVector(random(width), random(height)));
}

function draw(){
  background(255);
  for(let i = 0 ; i < randomLocations.length; i++){
    let loc = randomLocations[i];
    image(gif, loc.x, loc.y, 64, 64);
  } 
  text("click to add new random position", 10, 15);
}
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.0/p5.min.js"></script>

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66646944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档