Creating a movie in Jython/Python

2019-02-19 16:06发布

问题:

I am trying to make a movie, whilst creating frames through a loop. It is saving, but only the first frame (which it plays as a movie - short movie!) I've tried various things and cannot figure out what I am doing wrong. Thanks

def synthesiseFrame(folder):
  folder =r"D:\FOLDER"
  m=0.5
  for x in range(1,121):
    pic=makeEmptyPicture(960,540)
    for x in range (0,960):
      for y in range (0,540):
        r=#some code
        g=#some code
        b=#some code
        color =makeColor (r,g,b)
        px= getPixel (pic, x, y)
        setColor(px, color)
    numStr=str(x)

    m=m+0.0125
    if x<10:
      writePictureTo(pic, folder+"\pic00"+numStr+".png")
    if x >=10 and x<100:
      writePictureTo(pic, folder+"\pic0"+numStr+".png")
    if x>=100:
      writePictureTo(pic,folder+"\pic"+numStr+".png")

  return movie

movie=synthesiseFrame(folder)
folder =r"D:\FOLDER"
file=r"D:\FOLDER\pic00.png"
movie=makeMovieFromInitialFile(file)
writeQuicktime(movie,"D:\FOLDER\movie.mov", 30)
playMovie(movie)

回答1:

My first sight at JES video functions and at your code tells me something like (fully working example):

import os
import random

def synthesizeFrameAndCreateMovie(folder):

  # Create an empty movie to receive the frames
  movie = makeMovie()

  # Compute & save the frames
  w = 40
  h = 25
  nb_frames = 60       # Will give 60 frames at 30 fps => movie duration : 2 sec.
  for z in range(0, nb_frames):
    pic=makeEmptyPicture(w, h)
    for x in range (0, w):
      for y in range (0, h):
        #makeColor() takes red, green, and blue (in that order) between 0 and 255
        r = random.randint(0, 255)
        g = random.randint(0, 255)
        b = random.randint(0, 255)
        color = makeColor(r,g,b)
        px = getPixel(pic, x, y)
        setColor(px, color)

    # Create one frame and inject in the movie object
    filename = os.path.join(folder, 'pic%03d.png' % z)
    writePictureTo(pic, filename)
    addFrameToMovie(filename, movie)

  # return the movie
  return movie

movie = synthesizeFrameAndCreateMovie("D:\\FOLDER")
print movie
#writeQuicktime(movie,"D:\\FOLDER\\movie.mov", 30)
playMovie(movie)


Output (frames):


.............................................


EDIT :

More fun : animating a line (code taken form here)...

import os
import random

# Draw point, with check if the point is in the image area
def drawPoint(pic, col, x, y):
   if (x >= 0) and (x < getWidth(pic)) and (y >= 0) and (y < getHeight(pic)):
     px = getPixel(pic, x, y)
     setColor(px, col)


# Draw line segment, given two points
# From Bresenham's line algorithm
# http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
def drawLine(pic, col, x0, y0, x1, y1):

   dx = abs(x1-x0)
   dy = abs(y1-y0) 
   sx = sy = 0

   #sx = 1 if x0 < x1 else -1
   #sy = 1 if y0 < y1 else -1

   if (x0 < x1): 
     sx = 1 
   else: 
     sx = -1
   if (y0 < y1):
     sy = 1 
   else: 
     sy = -1

   err = dx - dy

   while (True):

     drawPoint(pic, col, x0, y0)

     if (x0 == x1) and (y0 == y1): 
       break

     e2 = 2 * err
     if (e2 > -dy):
       err = err - dy
       x0 = x0 + sx

     if (x0 == x1) and (y0 == y1):
       drawPoint(pic, col, x0, y0)
       break

     if (e2 <  dx):
       err = err + dx
       y0 = y0 + sy 

# Draw infinite line from segment
def drawInfiniteLine(pic, col, x0, y0, x1, y1):
   # y = m * x + b
   m = (y0-y1) / (x0-x1)
   if (abs(m) > 100.0):
     m = 100.0

   # y0 = m * x0 + b   =>   b = y0 - m * x0
   b = y0 - m * x0

   x0 = 0
   y0 = int(m*x0 + b)
   # get a 2nd point far away from the 1st one
   x1 = getWidth(pic) 
   y1 = int(m*x1 + b)

   drawLine(pic, col, x0, y0, x1, y1)

# Draw infinite line from origin point and angle
# Angle 'theta' expressed in degres
def drawInfiniteLineA(pic, col, x, y, theta):

   # y = m * x + b
   dx = y * tan(theta * pi / 180.0)  # (need radians)
   dy = y

   if (dx == 0):
     dx += 0.000000001 # Avoid to divide by zero 

   m = dy / dx

   # y = m * x + b   =>   b = y - m * x
   b = y - m * x

   # get a 2nd point far away from the 1st one
   x1 = 2 * getWidth(pic)
   y1 = m*x1 + b

   drawInfiniteLine(pic, col, x, y, x1, y1)


def synthesizeFrameAndCreateMovie(folder):

  # Create an empty movie to receive the frames
  movie = makeMovie()

  # Compute & save the frames
  w = 40
  h = 25
  nb_frames = 120       # Will give 120 frames at 30 fps => movie duration : 4 sec.
  for z in range(0, nb_frames):
    pic = makeEmptyPicture(w, h)
    addRectFilled(pic, 0, 0, w-1, h-1)
    #makeColor() takes red, green, and blue (in that order) between 0 and 255
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    col = makeColor(r,g,b)
    theta = z * 360 / nb_frames
    if (theta != 180.0) and (theta != 0.0):
      drawInfiniteLineA(pic, col, w//2, h//2, theta)

    # Create one frame and inject in the movie object
    filename = os.path.join(folder, 'pic%03d.png' % z)
    writePictureTo(pic, filename)
    addFrameToMovie(filename, movie)

  # return the movie
  return movie

movie = synthesizeFrameAndCreateMovie("/home/FOLDER")
print movie
#writeQuicktime(movie,"/home/golgauth/Desktop/FOLDER/movie.mov", 30)
#writeAVI(movie,"/home/golgauth/Desktop/FOLDER/movie.avi")
playMovie(movie)


Output (frames):


.............................................




回答2:

I changed your code.

  • Used '%03d'%x instead of if*3.
  • change 'pic00.png' to 'pic001.png' because the loop in synthesiseFrame start from 1.
  • '\' -> os.path.join(..); Put import os if you didn't.

def synthesiseFrame(folder):
  m = 0.5
  for frameNumber in range(1,121):
    pic=makeEmptyPicture(960,540)
    for x in range (0,960):
      for y in range (0,540):
        r = #some code
        g = #some code
        b = #some code
        color =makeColor (r,g,b)
        px= getPixel (pic, x, y)
        setColor(px, color)
    m += 0.0125
    writePictureTo(pic, os.path.join(folder, 'pic%03d.png' % frameNumber)) # 3 if -> no if
  return movie

movie = synthesiseFrame(folder)
folder = r"D:\FOLDER"
file = r"D:\FOLDER\pic001.png" # 00 -> 001
movie=makeMovieFromInitialFile(file)
writeQuicktime(movie,"D:\FOLDER\movie.mov", 30)
playMovie(movie)

EDIT

  • x (in outer loop) -> frameNumber