Placeholder Image

字幕列表 影片播放

  • (bell chimes)

  • - Hello, I am here today to make a coding challenge

  • about making a perfect,

  • well, whatever I make won't be perfect,

  • but you might make something perfect, GIF loop.

  • What is a GIF ?

  • Why am I talking about GIF loops?

  • One way that artists,

  • who work with computational media and computer graphics,

  • are distributing their work and expressing themselves,

  • is through posting GIFS

  • to various different online platforms.

  • An artist I would like to highlight is Saskia Freeke,

  • who has been making daily animated artworks

  • for quite a long time.

  • In fact, maybe there have been

  • at least 1500 of them, which is mind-blowing.

  • You can see a whole variety of them here on her Tumbler.

  • There's some others, I think she wrote a Medium article

  • about this process; they're amazing.

  • A vary famous GIF artist

  • that I have referenced in previous videos,

  • in fact we do the whole coding challenge

  • trying to recreate his Cube Wave,

  • is Bees & Bombs.

  • Bees & Bombs creates looping GIFs

  • through algorithms and math and graphics

  • in all sorts of astonishing mind-blowing ways.

  • So I encourage you to check out Bees & Bombs,

  • also Tumbler, to see all the kinds of GIFs

  • that he has created.

  • Golan Levin at Carnegie Mellon University,

  • a professor at Carnegie Mellon University,

  • gives an assignment every semester in his course,

  • interactivity and computation,

  • to create a GIF gallery.

  • To create a GIF.

  • And this is a gallery of GIFs

  • that students made in his course just this past fall.

  • Golan has a lecture about

  • loops throughout the history of art.

  • It's very easy to think as we work

  • on program the computer and make algorithms

  • visual and happen, and JavaScript in the browser

  • with your OpenGL shaders, WebGL magic,

  • that this is the first time any of this has happened.

  • But this kind of work has been happening

  • for years and years,

  • and predates the dawn of computers themselves.

  • This is a wonderful set of historical references

  • to different kinds of loops

  • that people have been making.

  • Of course, here's the iconic Muybridge galloping horse

  • that you can see here.

  • I encourage you to check out all these resources,

  • read about loops, and in fact,

  • you don't even need to watch this video.

  • You can go right here to Golan's loop templates,

  • which has templates for Java,

  • I'm sorry processing Java, p5.js JavaScript,

  • and Python processing, as well.

  • What I'm going to do though in this video,

  • is I'm going to make my own.

  • I'm not worrying about making something

  • artistic or innovative or beautiful;

  • I'm just going to try to to show the process

  • from start to finish of writing code and processing,

  • rendering it out to files,

  • and then packaging it up as a GIF that you could post.

  • I'm also going to come back and do a follow-up video.

  • There's a new p5 JavaScript GIF library

  • that some students of mine worked on

  • last semester in a course about open source,

  • so I will come back and show that

  • in a future video, as well.

  • Let's get started.

  • What is the driving principle of making a loop?

  • If you look at Golan's code examples,

  • the core idea is to have,

  • first, a total number of frames.

  • So a GIF, an animation, is just rendering

  • a whole bunch of images in sequence

  • at some frame rate for your eye to see,

  • and it appears like animation.

  • If whatever it is in the last frame,

  • or really what would be the last frame,

  • the sort of frame before the last frame,

  • matches up exactly with the first one,

  • then you have a loop.

  • In other words, if I'm drawing a circle here,

  • and then it goes to here, and then it goes to here.

  • Oh! (snickers)

  • Ah, I don't need that many frames!

  • (eraser scuffles)

  • Then, it goes to here, and then maybe it disappears.

  • I have a blank frame.

  • Then, in theory, the next frame I want to see

  • would be it entering the screen again,

  • but instead, I go back and show the first one.

  • So this will look like it's a loop

  • that's going on forever, whereas in reality,

  • it's just starting at the beginning,

  • and the last frame matches that,

  • and so as it goes back to the beginning,

  • it appears infinite.

  • So this is the idea.

  • A couple things we need to do,

  • we need to keep track of what is the total frames we want.

  • And then, I also want to have a variable called percent.

  • The idea is that percent

  • will always be the current frame count,

  • will be the current frame, the current frame number,

  • divided by the total number of frames.

  • What you'll see in Golan's example,

  • let's do the same thing,

  • is if we have the ubiquitous processing draw loop,

  • draws looping over and over,

  • we could actually put our codes somewhere else.

  • Maybe I'll write a function called render,

  • and we will just call that function

  • render passing in the percent.

  • This is a function that knows

  • how to render some kind of design,

  • based on what percentage of the way

  • through the design it is,

  • and as long as the design

  • is thought of in a way where the end matches the beginning,

  • then this is going to work out.

  • All the other stuff about saving frames,

  • is it recording, is it not recording,

  • that could be in the draw loop.

  • Okay, this is way too much explanation

  • for something that's, in essence,

  • quite a bit more simple.

  • All right there's two more things

  • I want to say about this.

  • One is Golan writes in his instructions to his student,

  • sketch on paper first, so I really recommend you do that.

  • If this is something you want to create,

  • try working this out with crayons, markers,

  • charcoal, pencil.

  • That's really helpful.

  • Going into that sort of analog drawing process

  • will really help you think through your ideas.

  • Number two is what are the kinds of algorithms

  • that move a value from one number to another number

  • and in fact, maybe wrap back around?

  • And there are all sorts of different kinds

  • of ways of doing this.

  • Probably, if you've watched any of my videos before,

  • you might be thinking of the sine function.

  • The sine function is an excellent function

  • to use for a GIF loop because if it starts

  • the sine function, if I were to graph the sine function,

  • where it starts, it repeats.

  • It's a repeating pattern over and over again.

  • You could also use, and then there's a ton

  • of different kinds of easing functions.

  • There's this lovely website called easings functions,

  • easings.net, which is an easings function cheat sheet,

  • and I highly recommend you explore

  • some of these other easing functions

  • to think about how you might move a value

  • through this loop.

  • If you go to Golan's code,

  • I'll just click on the processing one for a second,

  • you can see even in the code here,

  • there is a double-exponential easing sigmoid function.

  • Anyway, that's a wrap;

  • that's exploration you can do separately from this video.

  • Let's just get the basic mechanics working.

  • All right, so I have a blank processing sketch now.

  • I'm going to go add setup.

  • I'm going to draw, let's make it a square 400 by 400.

  • Let's make the background zero.

  • Ah, but no, no, no, no!

  • Let's make another function called render,

  • (typing)

  • and this function is going to take a value like percent,

  • and what I'm going to do is I'm going to say render percent.

  • I'm going to say the percent

  • is by the, I'm going to make my own variable called counter,

  • divided by the total frames.

  • So this means I need to say,

  • okay well, I want to have 120 total frames in this GIF.

  • I want to have a counter equal to zero,

  • and now here, let's just do something like say,

  • the ellipse, an ellipse is at percent times width,

  • this would a be linear function now,

  • at height divided by two, which is 20 by 20.

  • So we can see now,

  • if I say a counter plus plus,

  • and I'm going to say a float counter,

  • let's just see if this works for a second.

  • This is the idea that I have a total number of frames.

  • I have a counter that's going to go up.

  • I really want to start the counter at zero,

  • and then count up by one after render.

  • The idea here is that a much more complex,

  • sophisticated design with all sorts of

  • different kinds of easing equations could be in here,

  • but let's just see if this works.

  • I have some brackets out of place.

  • Oh, I have some weird extra slash here.

  • Let's see what happens, there we go.

  • So we can see it's moving across.

  • It's almost like the ball is moving,

  • because it's being drawn based on a percent.

  • Now, how would I determine how I want to render this?

  • I'm just going to have mine start recording

  • right when the program starts.

  • If you look at Golan's example,

  • it's a bit more sophisticated.

  • You press a key, it starts recording.

  • Here what I'm going to do is

  • I'm just going to say

  • right here, save frame,

  • GIF dash pound pound pound pound, or hash, png,

  • and I'm going to make a folder called output.

  • What this function does is

  • it saves an image to the directory output

  • associated with this processing sketch as a png.

  • Those hash symbols, or pound symbols,

  • indicate to processing that you want the file name

  • to be numbered based on the frame count.

  • (mutters)

  • I want to use my own counter.

  • This is going to use the automatic frame count,

  • which is probably fine,

  • but what I want to do is I'm going to say,

  • plus number format counter four, plus png.

  • So I'm going to add the counter number in here manually.

  • I think that's going to be better.

  • This number format function says

  • use four digits no matter what.

  • I guess I can just use three.

  • 'Cause I know I'm going to have 120 frames,

  • I only need three.png.

  • And then what I could say is if counter equals total frames,

  • I'm going to just basically say exit here.

  • I'm going to tell the program to stop.

  • So let's run this.

  • Okay, now

  • Let's look, I have a folder called output.

  • I look in there and we can see, there we go.

  • I have all my images.

  • So there are tons of ways now I could take this,

  • and stitch it together as a GIF.

  • I'll show you how to do the stitching later.

  • In fact, this new p5 library actually

  • will just create the GIF for you,

  • but it's kind of nice to have them as separate images.

  • We do have this question of,

  • do I have it matching up correctly?

  • We should see the last one should be 119,

  • and it's there so my algorithm is perhaps, not the best.

  • (chuckles)

  • This percent times width isn't really a perfect loop,

  • so that's something I might need to improve.

  • Let's make something that I know

  • will be a perfect loop.

  • For example, one thing that I could do now

  • is I could say, all right let's use rotate.

  • So I'm going to say angle equals percent times two pi,

  • (typing)

  • and I'm going to translate to the center of the window.

  • I'm going to say rect mode center.

  • I'm going to say no stroke, I mean no fill,

  • stroke weight two, and then I'm going to say

  • rectangle at zero, oh, rotate by some angle.

  • Rectangle, uh uh, let's use square,

  • square at zero, zero,

  • with a side length of 100.

  • Let's look at this.

  • Oh, what just happened?

  • No fill, oh stroke 255.

  • And this should have a fill of 255.

  • So now we can see this is spinning.

  • Now in theory, that's going to match up perfectly,

  • because that rotation at two pi

  • equals the rotation at zero,

  • and I'm rendering the very last frame

  • right before percent would be one,

  • in which case it would actually be two pi.

  • So this should match up perfectly.

  • Lets now, I'm going to comment this out.

  • Let's do this one more time.

  • Let that spin, stop;

  • now let's actually make it a GIF.

  • (bell chimes)

  • All right, so now that I've made all those images

  • and saved them to the output folder,

  • I'm going to try stitching them together as a GIF.

  • (chuckles)

  • I'm using this website called ezgif.com.

  • It must be easy 'cause it says so,

  • so I'm assuming this is going to work great.

  • But there's lots of other ways.

  • You could use Photoshop, you could use Ffmpeg,

  • there's all sorts of different software tools

  • that you can use to stitch images together into a GIF.

  • Lets see what happens if I select choose files.

  • Luckily for me, it's already going straight

  • to my output directory, but you'd have to find that

  • through your finder or

  • whatever operating system you're using.

  • I'm going to do select all.

  • I'm going to click open, and then I'm going to say,

  • upload, and make a GIF!

  • And this is going to work, right?

  • Oh look, so we can see.

  • Oh look at this, we can see all that the delay is 20.

  • 20 milliseconds would be, I guess that's somewhere

  • between 30 and 60 frames per second.

  • And somewhere here I should be able to say...

  • Oh, I can change the delay time.

  • So 60 frames per second would be 16.7.

  • Let's just leave it at 20.

  • Loop count, loop forever.

  • I'm not going to cross-fade frames.

  • What's interesting is that it has that effect.

  • Let's try this make a GIF.

  • Oh, but I have to wait now.

  • It's baking in the oven.

  • (cheerful music)

  • (alarm buzzes)

  • Okay, it says right there on the page,

  • in 1/100 of a second.

  • 1/1000 of a second is a millisecond,

  • so 32 milliseconds of delay is maybe around 30.

  • Let's make this three; we want 3/100 of a second.

  • Let's just try that; let's see what happens.

  • I mean, you might want it slower,

  • but I want it to kind of look like

  • how it looked like in processing,

  • so let me click this again.

  • There we go!

  • Look, there's my GIF, there's my GIF!

  • Is it perfectly looping?

  • Sort of hard to tell, but now

  • I should be able to download it.

  • I can probably just right click and do save image as,

  • and say, put it on the desk top.

  • Yay, I made a GIF, I made a GIF, I made a GIF!

  • (chuckles)

  • So you get the idea.

  • (sighs)

  • All right, so ultimately the creativity of what you design

  • is really the thing that I'm hoping

  • that you will discover in yourself to make something.

  • I mean, I just made a rotating square.

  • I think, in order to be able to explore your creativity,

  • you're going to need the tool you're working with

  • to be a bit more flexible.

  • Because right now, the way that I set this up,

  • is it kind of runs it once and then quits.

  • But I really want to be able to watch the thing loop,

  • and then change the code, and run it again.

  • Change the code, and run it again.

  • Then when I'm ready, hit record.

  • Let's do that this way.

  • I could do that through an interface,

  • but I'm just going to make a boolean variable called record,

  • and I'm going to set that equal to,

  • right now I'm going to set that equal to false.

  • Okay, so what I'm going to say here is,

  • I'm going to say float percent equals zero,

  • and this is very similar to Golan's, if record

  • then I am going to use this counter that I have.

  • (typing)

  • And then I'm also going to do all this stuff

  • like saving the frame.

  • Otherwise, I am just going to say percent

  • equals

  • float, the actual frame count.

  • I mean I could always use the counter.

  • This is silly, I should just always use the counter.

  • But frame count modulus total frames

  • divided by total frames.

  • So this should really be,

  • this is a little bit goofy,

  • but I'm going to put the percentage around here,

  • the parenthesis around there.

  • Okay, so let me give myself

  • a little bit more room to look at this code.

  • This is weird, I got to explain this for a second.

  • Why, why, why?

  • There we go, okay.

  • What I want to do here is I want to have the frame count

  • always cycle back to zero,

  • which I use the modulo operator,

  • and then I want to divide that by total frames.

  • But I want to convert that into a float,

  • so I don't need these extra parentheses

  • or this parentheses.

  • Yeah, no, yes, this is what I want, ah!

  • ♪ I will refactor this later

  • You know I will refactor this later

  • So now that recording is false,

  • this is just going to play the loop

  • forever and ever again.

  • I know that I ever want to now record it, right,

  • if I like my design, I can go

  • and delete what was there before.

  • Which I don't have to, it'll override it,

  • and I can change recording to true.

  • Then I can run it, it will do the recording,

  • and then it will quit out.

  • You know what?

  • There's a mistake here.

  • I am recording the last frame and I don't want to.

  • Let's look at the output here.

  • Yeah 120, I don't want 120.

  • Because 119 is the frame right before the starting frame,

  • the way that I've coded this,

  • so this save frame has to be here.

  • That's a quick fix.

  • Let me delete that again.

  • Let me run this.

  • Here it goes, record.

  • It's going to draw that last one, but that's fine.

  • Now, we should see the very last frame.

  • Shouldn't it exit before it does that?

  • All right, well, let's do it this way.

  • Let's just check if it gets to the end.

  • If it gets to the end, the frame before the last one,

  • then quit.

  • Now here we go, (gasps) that works.

  • I can see just based on where it's stopped.

  • Okay, great.

  • So this is what I want,

  • I want the last frame to match up before the first one.

  • Okay, great, so there's so much other stuff we could do.

  • I could use a sign wave.

  • Again, I would encourage you

  • to look at different easing functions,

  • and try all sorts of different kinds of designs,

  • and your only limitation for yourself

  • is that the end matches up with the beginning.

  • Matching up can mean a variety of different things,

  • 'cause something can leave the window,

  • and then enter again.

  • As long as there's visual continuity, your GIF will loop.

  • I will come back; I will show you also

  • how to do this in p5.js in the browser

  • with a special new p5 GIF library that I've been testing,

  • thanks to the creators of that library,

  • and I will come back and show that to you in a future video.

  • Please, ah!

  • Share you GIF loops!

  • We're going to have them all over the place, I dunno.

  • Coding train GIF loop, no what should it be?

  • Just share them.

  • (mimics crying)

  • Just look at this video's description.

  • I will explain how to share them.

  • Goodbye, thank you.

  • (upbeat music)

(bell chimes)

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

編碼挑戰135:在處理中製作GIF循環。 (Coding Challenge #135: Making a GIF Loop in Processing)

  • 4 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字