Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries. Thanks for all your past and future contributions.

(Difference between revisions)

Pop Art filter effect Halftoning using Imaging SDK

From Wiki
Jump to: navigation, search
galazzo (Talk | contribs)
(Galazzo - - Drawing dots)
croozeus (Talk | contribs)
m (Croozeus - Adding the correct template)
Line 2: Line 2:
{{Abstract|This article explains how to implement a filter effect inspired to [ Andy Warhol's Pop Art] using Halftoning technique.}}
{{Abstract|This article explains how to implement a filter effect inspired to [ Andy Warhol's Pop Art] using Halftoning technique.}}
{{Note|This is an entry in the [[Nokia Original Effect Wiki Challenge 2014Q2]]}}
{{Note|This is an entry in the [[Nokia Original Imaging Effect Wiki Challenge 2014Q2]]}}
{{ArticleMetaData <!-- v1.3 -->
{{ArticleMetaData <!-- v1.3 -->

Revision as of 08:19, 11 June 2014

This article explains how to implement a filter effect inspired to Andy Warhol's Pop Art using Halftoning technique.

WP Metro Icon Multimedia.png
WP Metro Icon WP8.png
Article Metadata
Tested with
Devices(s): Nokia Lumia 925, Nokia Lumia 1020, Nokia Lumia 1520, Nokia Lumia 630
Windows Phone 8
Created: galazzo (07 Jun 2014)
Last edited: croozeus (11 Jun 2014)


Pop art

Example of Pop Art

Pop art is an art movement that emerged in the mid-1950s in Britain and in the late 1950s in the United States. Pop art presented a challenge to traditions of fine art by including imagery from popular culture such as advertising, news, etc.

Pop art employs aspects of mass culture, such as advertising, comic books and mundane cultural objects. Pop art is aimed to employ images of popular as opposed to elitist culture in art, emphasizing the banal or kitschy elements of any given culture, most often through the use of irony. It is also associated with the artists' use of mechanical means of reproduction or rendering techniques.

Andy Warhol is probably the most famous figure in Pop Art, he is the father of the effect shown in the side image that we are going to reproduce through the Nokia Imaging SDK.


Halftone example.
Basically the effect we are going to create is made by composing the cartoon and Halftone effect. Nokia imaging SDK provide a good implementatoin of Cartoon filter, but not of the Halftone who is the one on which we will focus.

Halftone is a technique that simulates continuous tone of an image through the use of dots, varying either in size, in shape or in spacing, thus generating a gradient like effect.

Where continuous tone images contains an infinite range of colors or greys, the halftone process reduces visual reproductions to an image that is printed with only one color of ink, in dots of differing size. This reproduction relies on a basic optical illusion that these tiny halftone dots are blended into smooth tones by the human eye.

Dot shapes

Though round dots are the most common used, there are different dot types available, each of them having their own characteristics.

  • Round dots: most common, suitable for light images, especially for skin tones. They meet at a tonal value of 70%.
  • Elliptical dots: appropriate for images with many objects. Elliptical dots meet at the tonal values 40% (pointed ends) and 60% (long side), so there is a risk of a pattern.
  • Square dots: best for detailed images, not recommended for skin tones. The corners meet at a tonal value of 50%. The transition between the square dots can sometimes be visible to the human eye.

In this article we will focus on round dots as the algorithm is not dependent by the shape so once learned the techmique the user can use the one he prefer, also the most strange ones.

Creating the effect

There are plenty of tutorials and well done documentation explaining how to create a custom effect. As quick recap let's remember that to create a custom effect in managed code we need to inherit from CustomEffectBase while from DelegatingEffect in C++/CX.

In managed code, the basic looks like that:

public class DoubleEffect : CustomEffectBase 
public DoubleEffect(IImageProvider source) : base(source)
protected override void OnProcess(PixelRegion sourcePixelRegion, PixelRegion targetPixelRegion)

Drawing dots

As we learned in the description of the effect, basically the image to process is divided into cells, computed the average lumimosity of the area then plot on the correponding cell a dot ( or the shape you decided ) of the size related to the luminosity of the area. The darker is the area the bigger is the dot size and vice versa.

The cell size is a crucial choice for a good effect. If too small we risk simply to dirty the image as the effect is not well visible, if too big we loose all details. A good default value is a cell 20x20 pixels, but based on the image size the user should be able to set the size best fit his tastes.

The approach proposed divide the pixel's luminosity range into ten smaller ranges. This choice comes from a lot of tests and seems to be the best one, but the user is free to change it. The luminosity mapping is linear:

Range Dot size
[0,25] 20 pixels
[26, 50] 18 pixels
[51,75] 16 pixels
[76,100] 14 pixels
[101,125] 12 pixels
[126,150] 10 pixels
[151,175] 8 pixels
[176,200] 6 pixels
[201,225 4 pixels
[226,255] 2 pixels

What we need is a function that is able to build the dot template with the cell size and shape we decided to use that will be put on top of the processed area based on it's average luminosity.

The proposed function has the following code:

public class HalftoneEffect : CustomEffectBase
public HalftoneEffect(IImageProvider source)
: base(source)
protected override void OnProcess(PixelRegion sourcePixelRegion, PixelRegion targetPixelRegion)
private static void CreateDot(ref double[,] dot, uint outersize, uint innersize)
uint cx = outersize / 2;
uint cy = outersize / 2;
double _x = 0;
double _y = 0;
double distance = 0;
innersize /= 2;
for (int y = 0; y < outersize; y++)
for (int x = 0; x < outersize; x++)
_x = x - cx;
_y = y - cy;
distance = Math.Sqrt(_x * _x + _y * _y);
if (distance <= innersize)
dot[y, x] = 0;
dot[y, x] = 1;


197 page views in the last 30 days.