The pencil sketch effect that photo editors offer is not a neural network or complex algorithm. It is edge detection inverted to white lines on white background. The entire process takes four steps and runs in real time on canvas.
The algorithm
Step 1: Convert to grayscale.
Step 2: Invert the grayscale image.
Step 3: Apply Gaussian blur to the inverted image.
Step 4: Blend the grayscale and blurred-inverted images using "Color Dodge."
function photoToSketch(imageData, blurRadius = 20) {
const width = imageData.width;
const height = imageData.height;
const data = imageData.data;
// Step 1: Grayscale
const gray = new Uint8Array(width * height);
for (let i = 0; i < gray.length; i++) {
const idx = i * 4;
gray[i] = Math.round(0.299 * data[idx] + 0.587 * data[idx+1] + 0.114 * data[idx+2]);
}
// Step 2: Invert
const inverted = gray.map(v => 255 - v);
// Step 3: Blur the inverted image
const blurred = gaussianBlur(inverted, width, height, blurRadius);
// Step 4: Color Dodge blend
for (let i = 0; i < gray.length; i++) {
const idx = i * 4;
const dodge = Math.min(255, (gray[i] * 256) / (256 - blurred[i]));
data[idx] = data[idx+1] = data[idx+2] = dodge;
}
return imageData;
}
Why this works
The Color Dodge blend mode divides the base layer by the inverse of the blend layer. When the blurred-inverted layer is close to white (which happens in areas without edges), the result is white. When the blurred-inverted layer is dark (which happens at edges), the result preserves the original grayscale detail.
The effect is that flat areas become white (paper) and edges become dark lines (pencil strokes). The blur radius controls the "pencil thickness." Larger blur produces thicker, softer lines. Smaller blur produces finer, more detailed lines.
Adjusting the effect
Blur radius: 10-15 for detailed sketches, 20-30 for artistic sketches, 40+ for bold outlines only.
Edge emphasis: Adding an edge detection pass (Sobel or Canny) before the sketch conversion emphasizes strong edges and reduces noise.
Pencil texture: Overlaying a paper texture on the result adds realism. The texture should be subtle, about 5-10% opacity.
// Add paper texture
function addTexture(sketchData, textureData, opacity = 0.08) {
for (let i = 0; i < sketchData.data.length; i += 4) {
const texVal = textureData.data[i % textureData.data.length];
sketchData.data[i] = Math.min(255, sketchData.data[i] + texVal * opacity);
sketchData.data[i+1] = Math.min(255, sketchData.data[i+1] + texVal * opacity);
sketchData.data[i+2] = Math.min(255, sketchData.data[i+2] + texVal * opacity);
}
}
For converting photos to pencil sketch style directly in the browser, I built a converter at zovo.one/free-tools/photo-to-sketch. Upload a photo and adjust the blur radius and edge intensity to control the sketch style. It processes entirely client-side.
I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.
Top comments (0)