Hey Daniel, it's always impressive when you show us stuff in 30min, I use in Photoshop since 20 Years. Really love your channel and challenges and dithering ;-) .
I think it would be great if you did a challenge where you create an upscaling algorithm, similar to bilinear and linear upscaling you can find in programs like photoshop. There are some very advanced ones out there too that you can find in emulators for old pixel art games, although I don't know the names of them on the top of my head
legobudgie it's okay! I'm just a freshman in University, and just learning as well:) I know python and c++ the best, and any java or js I know is from that hunk on screen
All of your coding challenges are great, they are so much entertaining and give tons of ideas to beginners wondering what to code. Plus you really make them easy to follow..... but perhaps a little bit too easy. I definitely know you do that for the sake of clarity, but sometimes it makes your code choices really ugly and unseemly. I honestly think it would be really important for your viewers to see you working more on the code rather than the ouput only, even though it doesn't make it more impressive.
Just a note on this, if translating to another language the "r = r + errR * 7/16.0" parts can give you values 255 which will cause artefacts. your rgbs need to be clamped so if 255 =255.
I'm not great at coding but just found this channel and loving it. I feel like this guy would really like Return of the Obra Dinn since that's basically a game made with dithering.
thanks for great tutuorial! I"m attending the 2022 Genuary challenge and found your dithering challenge! Trying to translate the code from processing to P5js.
for " r = round(r/255)*255", if you are in optimization, I think that an if statement is better, since you only do one test rather than a division, a test and a multiplication (the test come from the round function, i'm not sure how it's implemented in java, but the fastest way that I can think about comes with a test... and a few more number manipulations (I'd guess a truncation, a subtraction, a test and an addition)... In this case the optimization doesn't matter much since you only compute a relatively small image once on a powerful enough computer, but I had once a occasion where little optimizations like this helped a small computer do image processing much faster, reduced the time by a factor of at least 50... Or you could do it with 'r = r/128' if r is an integer (which I think it is) to get only one line, I think it should be a bit slower than the if statement, though I'm not sure, not too too familiar with assembly yet
You have to consider when you do branching, the processor have to do a branch-predication. Basically, when it can take two different code branches, it'll guess which path the program will take and load code for one of the branches. This is so it can do optimizations as *out of order execution*, and *parallelism*. However, guessing wrong branch means that everything it has loaded and calculated in advance must be discarded, and the correct code has to be loaded. This is **slow**! So to know whether an if-statement is faster, you'll have to do what all optimization questions require; you have to measure it yourself!
I had an idea, take a dithered image and reverse it back into a continuous image but make it so that new image is much smaller than the original but still approximates the dithered image so it could be recreated from the smaller data set. A sort of lossy compression.
I had the same question. Now I would like to see how the dithering behaves as we slowly introduce slight variations in the palette thresholds and definitions (or also mixing the RGB channels).
Again super interesting and learned a lot, would have liked to see an example on the whiteboard to see what the formula of 7/16, 3/16, 5/16 and 1/16 on those surrounding dots was doing though You can sort of imagine it, but visualizing it would have been cool
I like processing. I've been playing with it for a bit, it's just that for some reason visual Studio doesn't like it. My apache server no prob. Thanks these videos are helping me get better.
If you're interested in image stippling, look up "poisson dart throwing" and "void-cluster method". A little trade secret, if you mean to apply relaxation to a stippled image, you might have to sharpen it a bit. Error diffusion will sharpen it a bit for you (that's partly why it's so popular), but other methods won't.
Hmmm, this reminds me... have you ever seen Raven Kwok's work for Karma Fields? The videoclip for Greatness and the one for Skyline are just beautiful. Would love to see you try something like those. Anyway, thanks for the one more coding challenge!
Don't you need a blank image to start with when you start accumulating the error distribution? It looks like you're adding to the original image over and over again ( you can see it change quite a few times 24:48 ). It should look much nicer than this.
i feel like this would be a very handy method for increasing the resolution of an image (if you added pixels between each existing one to create a larger image)
You did index ineffficiently ( 6:18 ). you should've done: int index = 0; for( int y = 0; y < kitten.width; y++ ){ for( int x = 0; x < kitten.height; x++ ){ /* drawiing */ index ++; } }
Excellent video -- Love the style and simplicity !!! Congrats!! Isn't there a hidden trick that each pixel is processed after it is changed? If the pixels at X,Y is show as @ for where we are AT then the four neighbors are ABCD the grid looks like . @ A B C D The Pixels at A B C D will be processed again once X++ increments and Y++ increments Can you explain this effect?
How are the weights 7, 3, 5, 1 determined? Well, if you feed a middle gray image (r=g=b=127 or 128) then you should get a checker board pattern when using 2 colors only (b/w). One big problem is that you don't get the expected result with these weights but strange artifacts will occur in the image. Try 7, 3, 4, 1 instead and then your result will be correct...
No, this wouldn't make any sense for several reasons. First of all there is no point in having the error of a pixel on the right border to affect the pixel on the left border. The idea is to spread the error to the neighbor pixels and the left side is pretty far away from the right side ^^. Next problem is this would completely mess up those pixels. The algorithm relies on the fact that a processed / quantized pixel is never touched again. The error of the current pixel is only spread onto pixels that hasn't been processed yet. So the error adding is actually a preparation step before you quantize the pixel. The proper handling would be to not doing those steps when the x or y index is out of bounds. The easiest solution in his code would be to implement the bounds check inside the index method and when the index is out of bounds return "-1". Now we can simply check before each of those 4 steps if we got a valid index (index >= 0) int index = index(x + 1, y); if (index >= 0) { // ... } The index method could be changed into float index(int x, int y) { if (x < 0 || y < 0 || x >= kitten.width || y >= kitten.height) return -1; return x + y * kitten.width; }
10:50, wouldn't that be five options? 0,1,2,3,4 (0*4=0, 0*4=4) with 0 and 4 being least likely? Round should be floor or ceiling in this case right? Watched another five seconds hahaha..... 😬
You guys, the algorithm is NOT that complex. Here is the psuedo code: By the way, I love yor channel :) variable x = -0.25 for( every pixel on canvas ): { | p = corresponding pixel of image | convert p to a brightness value (black and white), from 0 to 1, with 0 being black, and 1 being white | increment x by p | // note: a negative chance is treated as false, meaning the if will fail | if( this random chance from x - 0.125 to + 0.125 ): { | | color in the square on the canvas white | | x = -0.25 | } | elsewise: { | | new x = prev x + 0.1; | | color in the square of the canvas black | } } Want you picture dithered in color? That's is very similar. I will **bold** the differences for you. Color dither psuedo code: variable x = -0.25 for( every pixel on canvas ): { | p = corresponding pixel of image | **set the color C as the normal color value of p** | **set the color I as the inverted color valud of p ( inverted means opposite brightness and hue )** | increment x by p | // note: a negative chance is treated as false, meaning the if will fail | if( this random chance from x - 0.125 to + 0.125 ): { | | color in the square on the canvas **with the color C** | | x = -0.25 | } | elsewise: { | | new x = prev x + 0.1; | | color in the square of the canvas **with the color I** | } } If you desire a more complex dithering the draws circles rather than individual pixels, here is its psuedo code: choose your own value, this is the radius of the circles : | radius = 5 constant area = radius * radius * pi; variable x = -0.25 create another 2d array, named "circle bois", with its width = floor( canvas width / radius ), and its height = floor( canvas height / radius ), every cell should be a boolean (1 or 0) (true or false) for( every pixel on canvas ): { | p = corresponding pixel of image | convert p to a brightness value (black and white), from 0 to 1, with 0 being black, and 1 being white | increment x by p | calculate n, as how many of the 8 neighboring pixel regions are already white, by: | | "cicle bois" at ( | | | x: floor( this pixel's x / radius ) + or - 1, | | | y: floor( this pixel's y / radius ) + or - 1 | | ) | // careful with that calculatio, as it has 8 steps and some must be skipped when we are at the edge of the drawing | // we just used "circle bois to count how many circles have already been drawn near by (roughly)" | | // note: a negative chance is treated as false, meaning the if will fail | if( this random chance ( from x - 0.125 to + 0.125 ) * ( 1 - n /8 ) / ( area ) ): { | | draw the circle, centered at this pixel | | color in the circle on the canvas white | | x = -0.25 | | we want to save to circle bos now, so | | | set "cicle bois" at ( | | | | x: floor( this pixel's x / radius ), | | | | y: floor( this pixel's y / radius ) | | | ) | | | equal to true | } | elsewise: { | | new x = prev x + 0.1; | | color in the square of the canvas black | } } I decided to make all of this in codepen while I was at it. Here is pixel by pixel dithering : codepen.io/simon-will-over/pen/dyNeQVZ And here is circle dithering : codepen.io/simon-will-over/pen/PoWexJy
21:56 Is this really a problem? It's not just 7 divided by 16, it's the error * 7 / 16. And it goes in that order from left to right, so it's first multiplied by 7. It will not be zero unless error is less than 3.
Since you didn't go to the very right and the very bottom of the image, will those pixels still be quantized? I feel like they are not because those pixels are never checked, right?
I once read the rgb values from a 1024x1024 image (somewhere around there, can’t remember the exact dimensions, I guess it’s the default that the camera takes them) on an iPhone 5 using Swift and it took a few seconds to put those rgb values in a string so I could send them via HTTP to a game server where it would re-construct the image. In the end it looked very pixelated for some reason, you could kinda make out the outlines. Sorry, I completely forgot where I was going with this, I typed so much I don’t want to delete. :c
I probably have bad programming habits ! i'm learning ! I use a lot of conditional branching like if (r > 200 ) {r = 255} . will this slow down my program if a check each pixel in an image? i use about every 10th pixel to speed things up !
You should always end the challenge videos by making something crazy with the code. Like in this one, make moving particles or whatever. In any case doing that would conclude the video and give it a final bang. As you do it now asking your viewers to come up with cool ways to improve you leave us with an anticlimax. I'm a beginner coder and there's no way i can do this today and i bet most of your viewers actually enjoy the show rather than trying to comprehend the code.
if you use a `map` pattern, you won't need all these stupid names and code repetitions. first you do quantization transform, that maps color values to pairs of (color, error) values, then you make a map on a sliding window of values. there is one and only right way to implement this: through `map` and generators. it is easy to write, read and parallelize.
Hey Dan! Great video. I have a question: since I'm more acquainted with JS, I tried coding it in p5, following those instructions (and checking p5 ref to verify the commands exist). Even stippling alone doesn't seem to work at all. I then checked your GitHub source and saw that it was much quicker to code in .pde than in p5, what with all the long functions. I was wondering, is that because of the difference between JS and Java array structure? You can't simply grab a pixel from the array and get its blue value with one line of p5 code? Keep on being awesome ;)
Two questions: when you round the color values, isn't that also a function which uses an if statement? If so, is round() not only more elegant to write, but also faster though? And by that I mean something that's going on under the hood in the implementation of processing.
I like these videos, but sometimes I wish he'd make functions -- "I'm going to copy this block of code n times" should always be followed by, "So, I'll make a function."
"Sorry I lost my.... What I was doing here for a second"
Pretty much sums up Dan's way of working. :-p
You Dutch?
and that's a good thing
Curb Your Enthusiasm for Coding. Loving the intensity and your videos. Thanks Dan(LD)!
I've known about Floyd-Steinberg Dithering, but never looked into the algorithm. I never knew it was so simple!
Hey Daniel, it's always impressive when you show us stuff in 30min, I use in Photoshop since 20 Years. Really love your channel and challenges and dithering ;-) .
Thank you!
Your videos are not only comprehensive but also FUN. Thank you.
I like this guy. he is so enthusiastic and full of energy.
Really teaches me how much of a newB I am at programming
3 years later. Are you an oldG yet?
i mean, the coding train, tsoding, and theprimagen are the gods of youtube programming
I think it would be great if you did a challenge where you create an upscaling algorithm, similar to bilinear and linear upscaling you can find in programs like photoshop. There are some very advanced ones out there too that you can find in emulators for old pixel art games, although I don't know the names of them on the top of my head
like hq4x
Someday when I'm bored I'm going to recreate all these in python
I have done so to a couple, and be warned, pixel manipulation is not as fast.
Carter Plasek I know, but it's still fun
Oh, of course, python is certain to grant a good time :D
legobudgie it's okay! I'm just a freshman in University, and just learning as well:) I know python and c++ the best, and any java or js I know is from that hunk on screen
Everybody started out like that. Even all those geniusses like Dan or Alan Turing or whoever.
Hey man, just wanted to say that your videos are simply awesome. Cheers!
All of your coding challenges are great, they are so much entertaining and give tons of ideas to beginners wondering what to code.
Plus you really make them easy to follow..... but perhaps a little bit too easy. I definitely know you do that for the sake of clarity, but sometimes it makes your code choices really ugly and unseemly.
I honestly think it would be really important for your viewers to see you working more on the code rather than the ouput only, even though it doesn't make it more impressive.
Thanks for this feedback, I completely understand what you mean and will consider this in the future.
Thanks a lot for your reply and even more for your consideration, I'll look forward to it!!
I love watching his videos just for entertainment but I would love to see more practical approaches to some subject
Too Easy? AHAHAHAHAH
Just a note on this, if translating to another language the "r = r + errR * 7/16.0" parts can give you values 255 which will cause artefacts. your rgbs need to be clamped so if 255 =255.
I'm not great at coding but just found this channel and loving it. I feel like this guy would really like Return of the Obra Dinn since that's basically a game made with dithering.
Dude I'm not even a programmer but this was really interesting! Kept my attention the entire time.
I love this guy. He is hilarious... And a programmer!? Xd
Darn, I love these coding videos 🙌🙌 well done
Thanks for the wonderful performance!
thanks for great tutuorial! I"m attending the 2022 Genuary challenge and found your dithering challenge!
Trying to translate the code from processing to P5js.
23:25 how I feel any time I finish writing in JavaScript and don't want to break it with missing closures again
for " r = round(r/255)*255", if you are in optimization, I think that an if statement is better, since you only do one test rather than a division, a test and a multiplication (the test come from the round function, i'm not sure how it's implemented in java, but the fastest way that I can think about comes with a test... and a few more number manipulations (I'd guess a truncation, a subtraction, a test and an addition)... In this case the optimization doesn't matter much since you only compute a relatively small image once on a powerful enough computer, but I had once a occasion where little optimizations like this helped a small computer do image processing much faster, reduced the time by a factor of at least 50...
Or you could do it with 'r = r/128' if r is an integer (which I think it is) to get only one line, I think it should be a bit slower than the if statement, though I'm not sure, not too too familiar with assembly yet
Thanks for the feedback!
You have to consider when you do branching, the processor have to do a branch-predication. Basically, when it can take two different code branches, it'll guess which path the program will take and load code for one of the branches. This is so it can do optimizations as *out of order execution*, and *parallelism*. However, guessing wrong branch means that everything it has loaded and calculated in advance must be discarded, and the correct code has to be loaded. This is **slow**!
So to know whether an if-statement is faster, you'll have to do what all optimization questions require; you have to measure it yourself!
Yes a function is what I was thinking for that very similar block of code and repeated 3 times. And just pass the variations as parameters.
I had an idea, take a dithered image and reverse it back into a continuous image but make it so that new image is much smaller than the original but still approximates the dithered image so it could be recreated from the smaller data set. A sort of lossy compression.
YIPPI! Processing3 is used = +1000 points
A question Dan: why do that in the draw function? It's better do the loop once in the setup. Right?
Yeah, since this is generating a static image it makes sense for it all to happen one in setup!
I had the same question. Now I would like to see how the dithering behaves as we slowly introduce slight variations in the palette thresholds and definitions (or also mixing the RGB channels).
That awesome dithering effect at 14:44.
...but for fast cycle is better to use only one loop, for index
Where do you get all these awesome ideas? I'd love to attempt something like this myself but I wouldn't know where to start
Again super interesting and learned a lot, would have liked to see an example on the whiteboard to see what the formula of 7/16, 3/16, 5/16 and 1/16 on those surrounding dots was doing though
You can sort of imagine it, but visualizing it would have been cool
Lol... I just had a final exam from this topic
I wish I had final exams on topics like this
it's not as exiting when it's only theory and pseudocode :D :D
@@MrRys right
1:24 lands perfectly on the nose
i wanna smoke with this guy i feel like he'll talk your ear off then fall asleep eating a microwave burrito
I like processing. I've been playing with it for a bit, it's just that for some reason visual Studio doesn't like it. My apache server no prob. Thanks these videos are helping me get better.
The beard is getting more and more majestic
If you're interested in image stippling, look up "poisson dart throwing" and "void-cluster method". A little trade secret, if you mean to apply relaxation to a stippled image, you might have to sharpen it a bit. Error diffusion will sharpen it a bit for you (that's partly why it's so popular), but other methods won't.
Thank you for these great tips!
Hmmm, this reminds me... have you ever seen Raven Kwok's work for Karma Fields? The videoclip for Greatness and the one for Skyline are just beautiful. Would love to see you try something like those. Anyway, thanks for the one more coding challenge!
My man Daniel looking like Luke Skywalker
Ese Brooks Luke or Chewbacca - I can’t make up my mind... ;-)
Great the way you explain your thinking! So extremely helpful as i'm a beginner
this is nice for those who wants to show nice things on e-paper :)
In the p5 web editor, for some reason, even though you’re dithering it after displaying the original, it is showing the original dithered as well.
Would also love to see the curvy lines version that sort of looks like a maze... better yet... that is a maze.
you murdered youtubes compression lol
The easiest way to achieve this effect? GameBoy Camera.
Don't you need a blank image to start with when you start accumulating the error distribution? It looks like you're adding to the original image over and over again ( you can see it change quite a few times 24:48 ). It should look much nicer than this.
Fascinating! Go Dan!
Sitting here bored @ 12:30am... sees an upload from this mint fella! I love your attitude and enthusiasm, actually makes me interested in Hungary.
Damn autocorrect, meant to say that it makes me interested in things I would otherwise not.
Checked your time zone you are off.
Mazeyar Moeini I'm not in Hungary. That was autocorrect, I decided to leave it in there for the giggles.
Dan is looking good with the beared
I think I learned more about coding concepts from this video than I did from my $70,000 master's degree education.
i feel like this would be a very handy method for increasing the resolution of an image (if you added pixels between each existing one to create a larger image)
there wouldnt be more detail tho
I did this years ago in highschool for a project, i didnt know it was a thing that actually existed. I used processing also, thats so weird
„This is an integer, this is an integer. So it gives me an integer back“
But 255 divided by 4 is a float. I think it has to be 256 instead.
Wouldn't it be a rounded-down division instead?
Revi M Fadli sorry you‘re right. I disregarded the int cast.
You did index ineffficiently ( 6:18 ). you should've done:
int index = 0;
for( int y = 0; y < kitten.width; y++ ){
for( int x = 0; x < kitten.height; x++ ){
/* drawiing */
index ++;
}
}
You should take a look at real etching, woodcuts and lithography images. You would not believe how amazing some of those images are.
Swap for loops for better perf
I'd do luminosity grayscale instead of color in the first step
Excellent video -- Love the style and simplicity !!! Congrats!!
Isn't there a hidden trick that each pixel is processed after it is changed?
If the pixels at X,Y is show as @ for where we are AT
then the four neighbors are ABCD the grid looks like
. @ A
B C D
The Pixels at A B C D will be processed again once X++ increments and Y++ increments
Can you explain this effect?
How are the weights 7, 3, 5, 1 determined? Well, if you feed a middle gray image (r=g=b=127 or 128) then you should get a checker board pattern when using 2 colors only (b/w). One big problem is that you don't get the expected result with these weights but strange artifacts will occur in the image. Try 7, 3, 4, 1 instead and then your result will be correct...
you could use PVectors to store the RGB colors
I can’t stop staring at the floating tuft of hair at the beginning...😅
You should make a new video with the same algorithm as a SHADER.
I like your videos! And I was wondering if you could make an hypercube animation on Processing...
Could you use %amount of pixels in the index() function to get rid of out of bound errors, and make it rewind to the top?
Btw yes, rip bitrate
No, this wouldn't make any sense for several reasons.
First of all there is no point in having the error of a pixel on the right border to affect the pixel on the left border. The idea is to spread the error to the neighbor pixels and the left side is pretty far away from the right side ^^.
Next problem is this would completely mess up those pixels. The algorithm relies on the fact that a processed / quantized pixel is never touched again. The error of the current pixel is only spread onto pixels that hasn't been processed yet. So the error adding is actually a preparation step before you quantize the pixel.
The proper handling would be to not doing those steps when the x or y index is out of bounds. The easiest solution in his code would be to implement the bounds check inside the index method and when the index is out of bounds return "-1". Now we can simply check before each of those 4 steps if we got a valid index (index >= 0)
int index = index(x + 1, y);
if (index >= 0)
{
// ...
}
The index method could be changed into
float index(int x, int y)
{
if (x < 0 || y < 0 || x >= kitten.width || y >= kitten.height)
return -1;
return x + y * kitten.width;
}
10:50, wouldn't that be five options?
0,1,2,3,4 (0*4=0, 0*4=4) with 0 and 4 being least likely? Round should be floor or ceiling in this case right?
Watched another five seconds hahaha..... 😬
How did you learn all this stuff? You're super awesome.
I think it would get a better result if you used srgb to quantize the colors.
You guys, the algorithm is NOT that complex. Here is the psuedo code:
By the way, I love yor channel :)
variable x = -0.25
for( every pixel on canvas ): {
| p = corresponding pixel of image
| convert p to a brightness value (black and white), from 0 to 1, with 0 being black, and 1 being white
| increment x by p
| // note: a negative chance is treated as false, meaning the if will fail
| if( this random chance from x - 0.125 to + 0.125 ): {
| | color in the square on the canvas white
| | x = -0.25
| }
| elsewise: {
| | new x = prev x + 0.1;
| | color in the square of the canvas black
| }
}
Want you picture dithered in color? That's is very similar. I will **bold** the differences for you. Color dither psuedo code:
variable x = -0.25
for( every pixel on canvas ): {
| p = corresponding pixel of image
| **set the color C as the normal color value of p**
| **set the color I as the inverted color valud of p ( inverted means opposite brightness and hue )**
| increment x by p
| // note: a negative chance is treated as false, meaning the if will fail
| if( this random chance from x - 0.125 to + 0.125 ): {
| | color in the square on the canvas **with the color C**
| | x = -0.25
| }
| elsewise: {
| | new x = prev x + 0.1;
| | color in the square of the canvas **with the color I**
| }
}
If you desire a more complex dithering the draws circles rather than individual pixels, here is its psuedo code:
choose your own value, this is the radius of the circles :
| radius = 5
constant area = radius * radius * pi;
variable x = -0.25
create another 2d array, named "circle bois",
with its width = floor( canvas width / radius ),
and its height = floor( canvas height / radius ),
every cell should be a boolean (1 or 0) (true or false)
for( every pixel on canvas ): {
| p = corresponding pixel of image
| convert p to a brightness value (black and white), from 0 to 1, with 0 being black, and 1 being white
| increment x by p
| calculate n, as how many of the 8 neighboring pixel regions are already white, by:
| | "cicle bois" at (
| | | x: floor( this pixel's x / radius ) + or - 1,
| | | y: floor( this pixel's y / radius ) + or - 1
| | )
| // careful with that calculatio, as it has 8 steps and some must be skipped when we are at the edge of the drawing
| // we just used "circle bois to count how many circles have already been drawn near by (roughly)"
|
| // note: a negative chance is treated as false, meaning the if will fail
| if( this random chance ( from x - 0.125 to + 0.125 ) * ( 1 - n /8 ) / ( area ) ): {
| | draw the circle, centered at this pixel
| | color in the circle on the canvas white
| | x = -0.25
| | we want to save to circle bos now, so
| | | set "cicle bois" at (
| | | | x: floor( this pixel's x / radius ),
| | | | y: floor( this pixel's y / radius )
| | | )
| | | equal to true
| }
| elsewise: {
| | new x = prev x + 0.1;
| | color in the square of the canvas black
| }
}
I decided to make all of this in codepen while I was at it.
Here is pixel by pixel dithering : codepen.io/simon-will-over/pen/dyNeQVZ
And here is circle dithering : codepen.io/simon-will-over/pen/PoWexJy
Please make video for how to make online code editor using p5.js
21:56 Is this really a problem? It's not just 7 divided by 16, it's the error * 7 / 16. And it goes in that order from left to right, so it's first multiplied by 7. It will not be zero unless error is less than 3.
Can you do a heat map based on mouse pointer?
Yes. Could be done by adding a gaussian-distributed "heat" around the pointer. Perhaps a future coding challenge?
Since you didn't go to the very right and the very bottom of the image, will those pixels still be quantized? I feel like they are not because those pixels are never checked, right?
Correct.
what changes would i have to make to load a video file?
You: “pee-image”
My brain: “pie-mage”
Yes I am newB in p5. Not R nor G but only and only B
It's not showing the processed image on the right :/
int MewR... your kitten has imprinted itself on your brain ;)
I once read the rgb values from a 1024x1024 image (somewhere around there, can’t remember the exact dimensions, I guess it’s the default that the camera takes them) on an iPhone 5 using Swift and it took a few seconds to put those rgb values in a string so I could send them via HTTP to a game server where it would re-construct the image. In the end it looked very pixelated for some reason, you could kinda make out the outlines. Sorry, I completely forgot where I was going with this, I typed so much I don’t want to delete. :c
Can we do scribble style, is it possible?
Which editor are you using?
I probably have bad programming habits ! i'm learning ! I use a lot of conditional branching like if (r > 200 ) {r = 255} . will this slow down my program if a check each pixel in an image?
i use about every 10th pixel to speed things up !
21:54 You actually didn't need to put 16.0 because errR|G|B are floats. Default arithmetic order is x7 first then /16.
You should always end the challenge videos by making something crazy with the code.
Like in this one, make moving particles or whatever.
In any case doing that would conclude the video and give it a final bang.
As you do it now asking your viewers to come up with cool ways to improve you leave us with an anticlimax.
I'm a beginner coder and there's no way i can do this today and i bet most of your viewers actually enjoy the show rather than trying to comprehend the code.
Would this have been more efficient if you converted the image to grayscale first, then operated on just brightness values?
How about making an ASCII-art coding challenge? : P
if you use a `map` pattern, you won't need all these stupid names and code repetitions. first you do quantization transform, that maps color values to pairs of (color, error) values, then you make a map on a sliding window of values. there is one and only right way to implement this: through `map` and generators. it is easy to write, read and parallelize.
Hey Dan! Great video. I have a question: since I'm more acquainted with JS, I tried coding it in p5, following those instructions (and checking p5 ref to verify the commands exist). Even stippling alone doesn't seem to work at all. I then checked your GitHub source and saw that it was much quicker to code in .pde than in p5, what with all the long functions. I was wondering, is that because of the difference between JS and Java array structure? You can't simply grab a pixel from the array and get its blue value with one line of p5 code? Keep on being awesome ;)
check this video about pixel array in p5 ruclips.net/video/nMUMZ5YRxHI/видео.html
24 bit image to 8 bit image. Need to dither individual rgb channels.
At around 10:00 I'm curious, does Processing have a map(,,,,) function?
14:30 If you made those variables into one vector, you wouldn't have to repeat everything thrice.
I'm going to do this in OpenFrameworks in C++! :D
How does this effect the size of the image? What percentage of reduction does this produce in overall file size?
Two questions: when you round the color values, isn't that also a function which uses an if statement? If so, is round() not only more elegant to write, but also faster though? And by that I mean something that's going on under the hood in the implementation of processing.
You don't need to use an if statement in order to code your round function, for instance:
int round(float x){
return x+0.5;
}
Quentin Januel oh yes, I see. Cool trick. Thanks for The answer. :)
SellusionStar You are very welcome :)
15:24 oh bud did you break your arm at some point? That is a wicked scare you got on your elbow.
Indeed! 2 surgeries and a nice metal plate in there!
Epic bitrate drop at 24:50
Is this helpful when you have a beamer presentation but the resolution change makes your images look bad?
why does "x + y * image.width" work? Can you explain this?
I believe I cover that in this video! ruclips.net/video/EmtU0eloTlE/видео.html
I like these videos, but sometimes I wish he'd make functions -- "I'm going to copy this block of code n times" should always be followed by, "So, I'll make a function."
I have an API call that I use to generate the image url but I can't seem to pass it to this p5.js function; anyone else have this issue?
Hi! If you want help with code, the discord is a great place for that! thecodingtrain.com/discord
@@TheCodingTrain Thanks! I'll check it out 😊
This guy looks and sounds like he makes his coffee with red bull instead of water
why does it runs slow in python?
Still no ducks given about good looking self drawn grids