Reputation:
so I had been trying to create a coloring canvass drawing app and I found this github page and try it here and it works great.
but the problem happen when I want to change the image into something else. other than the duck I wanted to change it into mickey mouse but the brush tip on the app won't draw over the new image. it can only draw on the duck image
now my question is, what kind of image is acceptable for it to be drawn over? I can't find any explanation from the github page though. so I need help to explain the image requirement for it to be drawn over.
Upvotes: 1
Views: 1328
Reputation: 54109
The reason that the image you are using does not show the background inside the character's body is because there are white non transparent pixels covering what you are drawing.
You have three options.
Edit the image in photoshop (gimp, dotPaint, .. etc) and remove the white pixels. Easy.
Use getImageData and an offscreen canvas to remove the white pixels. Difficult and may have some problems.
Use the 2D context globalCompositeOperation "multiply" to draw the image. Easiest, with minor caveats.
As the easiest is option 3 and here is how to do it.
context.drawImage(outlineImage...
. (At line 283 of the file.)Was
// Draw the outline image
context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);
Change to
// Draw the outline image
context.globalCompositeOperation = "multiply"; // sets the comp op
context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);
context.globalCompositeOperation = "source-over"; // restore the original comp op state
The caveats are that it will only work well for black and white image. Below will explain why this is so.
Multiply performs a operation on each pixel and each pixel channel RGBA. For simplicity I represent all channels as C for colour. Where Cs is the source pixel (from image), and Cd is the destination pixel (the canvas)
The formula is
Cd = Cd * (Cs / 255);
Thus if a pixel is white Cs = 255
then you multiply the destination pixel with 255 / 255
which is 1. Cd * 1
so the colour remains the same. If the source pixel is black Cs = 0
then you multiply the destination with 0 / 255
which is 0. Cd * 0
is 0 so the pixel becomes black. Other values will reduce the luminance of the destination pixel. For gray Cs = 128
you have Cd * 128/255
or Cd * 0.5
approx
For RGB
Rd = Rd * (Rs / 255);
Gd = Gd * (Gs / 255);
Bd = Bd * (Bs / 255);
Thus is you have a red pixel [255,0,0] on the source and a white pixel on the destination [255,255,255] the result will be
255 = 255 * (255 / 255);
0 = 255 * (0 / 255);
0 = 255 * (0 / 255);
Tinting all pixel under the red pixel red
It is a little more complex than that as the alpha channel determines the amount the source image's RGB values affect the destination but for now the above explanation will help you understand how it works.
And you are ready to paint.
Upvotes: 1
Reputation: 7
You have
outlineImage.onload = resourceLoaded;
outlineImage.src = "images/watermelon-duck-outline.png";
inside your javascript.
How do you change your image ?
You need to prepare your canvas with the new image.
If it doesn't work you can try fabric.js.
var outlineImage = new Image();
function prepareCanvas(){
outlineImage.src = "images/mickeymouse.png";
}
Upvotes: 0