×
Namespaces

Variants
Actions

Psychedelic Custom Effect (Nokia Imaging SDK)

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to create a Psychedelic Effect, that will flip color components to their opposite extreme.

SignpostIcon XAML 40.png
WP Metro Icon WP8.png
Article Metadata
Tested with
Devices(s): Nokia Lumia 920
Compatibility
Platform(s):
Windows Phone 8
Dependencies: Nokia Imaging SDK 1.0
Article
Created: Rob.Kachmar (07 Feb 2014)
Last edited: Rob.Kachmar (18 Feb 2014)

Contents

Introduction

The PsychedelicEffect allows you to dim color components and have them flip to their opposite extreme if they go below zero.

The article provides links to the filter source code and test code, an explanation of how the filter works, and code snippets showing how it is used.

Source code

Full source code for the PsychedelicEffect custom effect is provided below (toggle "Expand") and also in a ready-to-use file here: PsychedelicEffect.cs.

PsychedelicEffect.cs (04 Feb 2014)

  1. // ============================================================================
  2. // DATE        AUTHOR                   DESCRIPTION
  3. // ----------  -----------------------  ---------------------------------------
  4. // 2014.01.20  Rob.Kachmar              Initial creation
  5. // ============================================================================
  6.  
  7. using Nokia.Graphics.Imaging;
  8. using System;
  9. using System.Collections.Generic;
  10.  
  11. namespace NISDKExtendedEffects.ImageEffects
  12. {
  13.     public class PsychedelicEffect : CustomEffectBase
  14.     {
  15.         private byte m_factor = 50;
  16.  
  17.         public PsychedelicEffect(IImageProvider source, byte factor = 50) : base(source)
  18.         {
  19.             m_factor = factor;
  20.         }
  21.  
  22.         protected override void OnProcess(PixelRegion sourcePixelRegion, PixelRegion targetPixelRegion)
  23.         {
  24.             var sourcePixels = sourcePixelRegion.ImagePixels;
  25.             var targetPixels = targetPixelRegion.ImagePixels;
  26.  
  27.             sourcePixelRegion.ForEachRow((index, width, position) =>
  28.             {
  29.                 for (int x = 0; x < width; ++x, ++index)
  30.                 {
  31.                     // NOTE: Just pulling out the color components and reassembling them brings you down to 14-15 FPS
  32.                     uint currentPixel = sourcePixels[index]; // get the current pixel
  33.                     uint red = (currentPixel & 0x00ff0000) >> 16; // red color component
  34.                     uint green = (currentPixel & 0x0000ff00) >> 8; // green color component
  35.                     uint blue = currentPixel & 0x000000ff; // blue color component
  36.  
  37.                     // Original accidental code
  38.                     //red = Math.Max(0, Math.Min(255, (uint)(int)(red - m_factor)));
  39.                     //green = Math.Max(0, Math.Min(255, (uint)(int)(green - m_factor)));
  40.                     //blue = Math.Max(0, Math.Min(255, (uint)(int)(blue - m_factor)));
  41.  
  42.                     // Max out any color component that falls below zero - 12-13 FPS
  43.                     red = (red < m_factor ? 255 : red - m_factor);
  44.                     green = (green < m_factor ? 255 : green - m_factor);
  45.                     blue = (blue < m_factor ? 255 : blue - m_factor);
  46.  
  47.                     // Reassemble each component back into a pixel and assign it to the equivalent output image location
  48.                     targetPixels[index] = 0xff000000 | (red << 16) | (green << 8) | blue;
  49.                 }
  50.             });
  51.         }
  52.     }
  53. }

Testing

The Test Apps for Viewing Custom Filters allow you to cycle through a number of different custom effects (including PsychedelicEffect) and apply them to the real-time camera preview or a static image.

In addition, the custom effect file can be dropped into your own project, and used as described in the section Using the filter.

Pre-requisites

Performance

Device PsychedelicEffect - factor of 25 PsychedelicEffect - factor of 50
Lumia 920 13-14 FPS 13 FPS

The PsychedelicEffect class runs around 13-14 FPS (Frames Per Second) depending on your factor choice.

Code walkthrough

This effect was created accidentally. I was working through the BrightnessEffect technique and wasn't handling the data type casting correctly (or even the correct brightness calculation for that matter).

  1. // Original accidental code
  2. red = Math.Max(0, Math.Min(255, (uint)(int)(red - m_factor)));
  3. green = Math.Max(0, Math.Min(255, (uint)(int)(green - m_factor)));
  4. blue = Math.Max(0, Math.Min(255, (uint)(int)(blue - m_factor)));

The above code doesn't make a whole lot of sense, and isn't terribly efficient, but it still produced a fun look, which looks especially wild through a realtime camera feed. I ended up rewriting it below, which is more efficient, and easier to understand what's actually happening.

  1. // Max out any color component that falls below zero when subtracting the passed 
  2. // in m_factor value; otherwise just subtract the m_factor value from it.
  3. red = (red < m_factor ? 255 : red - m_factor);
  4. green = (green < m_factor ? 255 : green - m_factor);
  5. blue = (blue < m_factor ? 255 : blue - m_factor);

Note.pngNote: If you pair up the PsychedelicEffect with the inbuilt WarpFilter of the Nokia Imaging SDK, you'll start to see just how much fun it can be.


Using the filter

Drop an image control into your XAML.

  1. <Image x:Name="FilterEffectImage" Width="800" Height="480" Stretch="Fill" Grid.RowSpan="2" />

Use this code to apply the filter effect to your chosen image and assign it to the XAML image control.

  1. // Initialize a WriteableBitmap with the dimensions of the XAML image control
  2. WriteableBitmap writeableBitmap = new WriteableBitmap((int)FilterEffectImage.Width, (int)FilterEffectImage.Height);
  3.  
  4. // Example: Accessing an image stream within a standard photo chooser task callback
  5. // http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394019(v=vs.105).aspx
  6. //using (var imageStream = new StreamImageSource(e.ChosenPhoto))
  7.  
  8. // Example: Accessing an image stream from a sample picture loaded with the project in a folder called "Pictures"
  9. var resource = App.GetResourceStream(new Uri(string.Concat("Pictures/", "sample_photo_08.jpg"), UriKind.Relative));
  10. using (var imageStream = new StreamImageSource(resource.Stream))
  11. {
  12.     // Applying the inbuilt warp filter and the custom effect to the image stream
  13.     IImageProvider imageEffect = new FilterEffect(imageStream) 
  14.     { 
  15.         Filters = new List<IFilter>() { new WarpFilter(WarpEffect.Twister, 0.50) } 
  16.     };
  17.     using (var customEffect = new PsychedelicEffect(imageEffect, 50))
  18.     {
  19.         // Rendering the resulting image to a WriteableBitmap
  20.         using (var renderer = new WriteableBitmapRenderer(customEffect, writeableBitmap))
  21.         {
  22.             // Applying the WriteableBitmap to our xaml image control
  23.             FilterEffectImage.Source = await renderer.RenderAsync();
  24.         }
  25.     }
  26. }

License

The code has been released with the standard MIT License, and can be viewed in the Github project here.


Summary

Hopefully you've enjoyed seeing a fun and wild thing you can do with your images. This is just one of many things you can do with the amazing Nokia Imaging SDK.

As with all articles on the wiki, you are welcome to contribute any changes to this code that would improve the quality, whether it be additional features or improving its efficiency.

This page was last modified on 18 February 2014, at 09:32.
68 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×