New Directional Rainbow Brush; Smear Effect; EasyPainter Out of Beta and Becomes Fantasia!

Jul 25, 2010

Yes! A lot of announcements today:

The new Fantasia Painter is here: http://nokola.com/fantasia/

  1. New Rainbow brush makes ultra cool smooth color transitions, based on stroke direction
  2. EasyPainter includes all Fantasia brushes and is now named Fantasia!
  3. Fantasia is out of Beta! There is new, enhanced Undo functionality, improved interface.
  4. Smear procedural brush effect makes for reallistic paint “feel” when drawing

Details below:

Rainbow Brush

The rainbow brush changes color based on stroke direction. It cycles through the color wheel.

Here’s a sample:

rainbow

Try making strokes multiple strokes from left-to-right, then from top-to-down, then from right-to-left to see how it feels :)

Fantasia Lite + EasyPainter = Love (= Fantasia Painter)

EasyPainter has all brushes, is out of beta and has an undo stack that is limited to 400 MB and captures undo data every second, if there is a change.

This allows even a mid-stroke undo capturing – a must have for nice experience with the new brushes.

I had this brush improvement in mind probably for the last 5-6 months. It’s nice to finally see it done.

Also, there is a small, but significant UI improvement – some extra margins are removes and a little bit of space is added between some controls. This makes the whole program easier to read. The background behind the image is a little darker too, to “give out the color” some more.

Smear Effect

All of the History procedural brushes (Sketch, Furs, Rainbow), now include “Smear mode”, which looks like this:

smear

Notice how the “Smear on” paint has some darker regions, and generally it looks and behaves like real paint. The “Smear off” paint is smooth, and generally looks more “sketchy”. I believe both painting modes have their use.

The smear is easily controlled from within Fantasia:

image

Technical details: The Smear effect is produced by varying the opacity slightly (e.g. from 243 to 255), and then drawing on black background. It’s not exactly random – I’m using a computation (truncation) “issue” with pre-multiplied alpha. When you draw low-opacity (< 20) object in Silverlight multiple times (e.g. 25 times), the alpha sometimes “magically transfers” making the image with less than 255 opacity. In short, the image can get corrupted due to rounding errors. I’m using this corruption to achieve the Smear effect. In a “perfect world” (where all computations are double and alphas are not premultiplied), you can achieve the same effect by lowering the destination alpha by 2 or so every time you draw a pixel with opacity < 10.

Last but not least: here’s a rabbit made by Burcu with Fantasia. Burcu is one of my new colleagues.

 

 rabbit

That’s all! Needless to say, I’m happy with Fantasia now.

Hope you like it too! Please comment!

Fantasia Lite: New Silverlight Painting Tool

Jul 22, 2010

Edit: Fantasia Painter (full version), is now available here: http://nokola.com/fantasia

Edit 2: The Fantasia Lite version below, has been updated to include the new Rainbow brush (source code included too).

Here’s what I built tonight – a drawing tool that utilizes procedural brushes to enable almost everyone to create fluffy rabbits like this:

rabbit

Note that it took me about 2 minutes to “build the rabbit”. I’m sure someone else can do better. Supposedly, it lives in the hole on the right.

Here’s the live app:

As usual: Download source code

Note that this whole thing is inspired by http://mrdoob.com/120/Harmony (HTML5 – doesn’t work in IE8 as I write this) which was originally inspired by http://www.zefrank.com/scribbler/gallery/index_ran.html. By the way, make sure to check the funny videos “How To Dance Properly” on Ze’s page: http://www.zefrank.com/invite/swfs/index2.html

I talked way back (March or something) with Mr. Doob and he released his Harmony code under the MIT license. His latest source code is now released under GPL though. I didn’t look at it since I wanted my sources to be MS-PL license-able.

What Is A Procedural Brush?

A typical “brush” will just draw whatever it is supposed to draw (e.g. connect dots with lines). It just needs the current and previous mouse position.

A procedural brush is “smarter”, since it takes more variables into account.

Fantasia’s brushes make use of the following data to modify the drawing output:

  • mouse position
  • velocity (how fast the mouse moved)
  • time between 2 consecutive dots
  • distance between dots
  • slope (angle) of the line between the last and current dot
  • the last N previous dots (N varies between 2 and 100000)

The Fantasia brushes modify these outputs:

  • Color (e.g. color can be changed based on angle which can produce cool output – I haven’t published this brush yet)
  • Opacity (the faster you move, the less visible the trace is, such as in the OldPen sample
  • Stroke width (again can be controlled by speed, or maybe by slope (angle), which produces a nice caligraphy effect)
  • Drawing other random lines

Here is the source code of few of the brushes:

The Line Brush – same as a “regular” brush, just connects dots with straight lines:

public override void Stroke(double x, double y, double dx, double dy, double timeMsec, double distance)
{
    _surface.Render(new Line() { X1 = _prevX, Y1 = _prevY, X2 = x, Y2 = y, Stroke = _brush }, null);
}

The Old Pen brush, uses velocity = distance / time, to modify the color intensity:

public override void Stroke(double x, double y, double dx, double dy, double timeMsec, double distance)
{
    _surface.Render(new Line()
    {
        X1 = _prevX,
        Y1 = _prevY,
        X2 = x,
        Y2 = y,
        Stroke = new SolidColorBrush(
            new Color()
                {
                    A = (byte)(255 - distance / timeMsec * 100),
                    R = (byte) (_color.R * (distance / timeMsec * 100)),
                    G = (byte) (_color.G * (distance / timeMsec * 100)),
                    B = (byte) (_color.B * (distance / timeMsec * 100)),
                })
    }, null);
}

The History brush, most complex so far and used for the sketch and Furs:

public override void Stroke(double x, double y, double dx, double dy, double timeMsec, double distance)
{
    _points.Add(new Point(x, y));
    if ((Memory > 0) && (_points.Count > Memory)) _points.RemoveAt(0);

    _surface.Render(new Line() { X1 = _prevX, Y1 = _prevY, X2 = x, Y2 = y, Stroke = _solidBrush }, null);

    foreach (Point p in _points)
    {
        double cdx = p.X - x;
        double cdy = p.Y - y;

        double dist2 = cdx * cdx + cdy * cdy;

        if ((dist2 < _activationDistance2) && (_random.NextDouble() > (dist2 / (_activationDistance2 * ActivationChance))))
        {
            _surface.Render(new Line() { X1 = x + cdx * ReachSource, Y1 = y + cdy * ReachSource, X2 = p.X - cdx * ReachDest, Y2 = p.Y - cdy * ReachDest, Stroke = _stroke }, null);
        }
    }
}

The history brush can also do internal highlights if the _stroke is set to a LinearGradientBrush.

There is also a prototyping Test brush: I’m trying to “smoothen” the line as it is getting drawn. It’s using binaries by Charlez Petzold: http://www.charlespetzold.com/blog/2009/01/Canonical-Splines-in-WPF-and-Silverlight.html

Hope you like it! Please comment!

  

Coolest Silverlight Sound Library for Games I’ve Seen Yet

Jun 10, 2010

Quite amazing demo: http://prefix.teddywino.com/post/SilverlightMediaKitLiveDemo.aspx 

The library has a lot of potential for Silverlight games. It does MP3 decoding in managed code and exposes some cool controls like Pitch, Echo. Duet is my favorite. I’m also a Transformers fan and like how Duet makes explosion and swoosh sounds sound “Transformerish”.

I believe it should solve the “short sound” and “looping music” issues with Silverlight without any problem :). The biggest coolness though is that you can now simulate doppler effects and have more “rich” sound in smaller package (for example, by keeping only one explosion.mp3 and varying the pitch slightly).

The CPU usage on my quad core q6600 is ~1-2% of one core for most of the effects. 11% for the Pitch and 8% for the duet.

You can download the source code here: http://salusemediakit.codeplex.com/ (MIT License)

Edit: another library, just released under CDDL License: http://vorbisplayer.codeplex.com/

Playing The Piano From Scratch

May 25, 2010

Yes! For the last month or so I have been studying the piano. Here are my first 2 pieces:

http://www.jamendo.com/en/album/67446

This is the reason why I haven’t done anything public in Silverlight recently. I’ve been also experimenting with the new Expression Blend and Phone 7 stuff.

Note that I started from 0 (zero) :) about 2 months ago, all by myself so coming from “Marry Had a Little Lamb” to the above music was definitely a trip and fun!

They are licensed under CC-BY-SA license. I’ll probably switch it to something even more permissive later.

Contents Of This Rather Long Post

Summary

Key Takeouts For Music – Nokola’s View

Key Takeours For Composers – Nokola’s View

Skills and How Piano is like Role Playing Games

3 Major Cheats For Beginners

Resources And Inspiration

 

Summary

Here is a summary of my experiences:

  • Piano playing can be very addictive. I started with the goal to play one song (the Meadow from New Moon) and ended up doing a lot of stuff.
  • It’s definitely not hard and it’s better if you like it :)
  • Playing with teacher or following “excercises” is not fun. I always did what I felt like – a lot more fun and I believe helps with development.
  • Composing your own stuff is not as hard as I thought, once you learn some “tricks”. It is a lot like software development :)

I started trying to play The Meadow, but after the first note line, decided to buy a book. Then got a “Learn & Play Keyboard“ – a book for absolute beginners that describes notes, durations, etc. The nice thing about it is that you can start playing immediately with 3 fingers and it builds nicely on top of that.

After finishing this (relatively) small book in about a week, I searched online and found this amazing piano course: http://pianoforall.com/

It’s one of those long sites that offers a lot of stuff with buy buttons and initially I thought it’s “just one of those buy now sites” but after researching I decided to buy the 10 books for ~$40… It was great! The author focuses on “getting the feel of music” from the start, not notation, reading and boring exercises. You begin to improvise almost from the start – great for having fun at your own pace! He will teach you several rhythm patterns then give you “chords” (chords are typically 3 or 4 notes pressed together) for common songs (Beatles, and many many other) so you can experiment. The nice thing is that you can actually understand why a music is composed the way it is, what sounds nice together (to some extent), etc.

After going through books 1-3 I decided to give The Meadow another try! It was much better this time, since I could recognize the patterns and didn’t have to just blindly memorize the notes from the sheet anymore (in fact I play a little different version of The Meadow since I didn’t pay 100% attention to the sheet all the time and probably deviated here and there).

The books contain also a lot of “tricks” “cheats” or “shortcuts” that basically help you “do the job” or “fake it” (produce nicely sounding things with not-so-much effort), which I liked a lot. There is some song that is amazingly simple and sounds (and looks) complex when played.

The key takeouts for music so far (for me):

  • Chords are groups of several notes (e.g. C, E, G) that sound nice together.
  • It doesn’t matter where the notes of the chord are located on the keyboard as long as their name is the same. For example, you can play C at the “bottom” of the keyboard, and E, G at the middle; or you can play the E at the top of the keyboard and G in middle – it’s still the same chord (C, E, G). This is crucial when “mixing” tones as you have much better knowledge of what tones mix “nicely” and what don’t.
  • By modifying a chord a little you can make it sound “mellow” “sad” “happy” or add “tension” (this is the feeling of “something not 100% right” when playing that can later “resolve” to the chord without tension)

The key takeouts for composing music (for me):

  • Composing can start with a very simple (3-4 seconds) melody that can be “enhanced” by using what I call “piano techniques” (not sure what other people call those):
    • Echo: Moving the melody up or down one octave (12 notes)
    • Key Shift: Very powerful technique, as it changes the mood dramatically. I don’t have this in the 2 songs above yet, but I did it last week in the Unbreakable Love and it sounds much improved! “Key shift” is just moving the melody few notes (not an octave) up or down. It works best if your transition between keys does not “jump” notes. For example if you switch from key A to key E, you can play a melody that somehow goes from A to E then shift. Imagine playing a Storyboard and suddenly have your animation jump – who would want that? Ideally, you would make your animations smooth and nice.
    • Time Shift: getting a bit sci-fi here :) Timeshift is just playing the melody gradually faster or slower in order to convey a feeling. It’s used in The Meadow (at least I do) after the second part of the song
    • Pitch Shift: Sometimes, you can add “color” to the music by quickly moving through one or more half-tone notes. For example, you can C, C#, D instead of C,D. It can add a “weird” mood feeling (“something is wrong”) which can make the music more interesting
    • Broken Chords: This just means “play C, then E, then G” instead of all 3 at the time. You can also “break” by playing C, then EG, or some other way. Broken Chords are also called Arpeggios
    • Crawl: If you play with both hands, and slow down one of them significantly (e.g. the right hand), you may end up with a completely new melody that sounds close to the original. One of my last week’s findings (no public music yet) :) Crawling makes music more “dramatic” and “determined” IMO. Or it could do for a sad ending or whatever :)
    • Burst: If you’re in a crawl (or just regular play), you can drastically increase the speed of some of the notes in the melody (it creates a new, similar melody)
    • Repetitions: I had some trouble (and still have) repeating notes – in fact it can help a lot with the music. On few occasions I’d find myself unable to find the “right” note when it was exactly under my finger :)
    • Chord Progressions: probably one of the most defining traits of your music. Progressing between chords means to switch from one chord to another, somehow. The “somehow” leaves a lot of room for interpretation. Given that a chord can be played in many octaves, across octaves, there is a lot of variation. I think a good way to start is by trying to change chords with the minimum number of note changes (e.g. from C, E, G to C, E, A)
    • Duplication: This means playing the same note (e.g. C) on a different octave. You can also do this with chords and play CCEG instead of just CEG.
    • Chord mode on/off: This is when you switch from playing melody to playing chords (happens for 2 times in Unbreakable love). Good when you want to “end a chapter” of the song and continue to the next.
    • Other: there are a lot other I don’t know (e.g. intervals, tremolo fired runs, fills, riffs or whatever else people are doing on youtube)
  • Be free to explore – for example, go one of few notes up and down when playing a melody, many times it sounds a lot more interesting this way
  • Songs usually follow a pattern, for example AXYXYXZ (or other) where X is one melody, Y is “choir” and A,Z are beginning and ending. You don’t have to follow the pattern just for the sake of it, but it sounds nice sometimes.
  • Try to “build up” the melody – for example if it’s “firm and strong” at the beginning, getting more soft towards the end, you probably may want it to get progressively “softer” (as compared to jumping from “strong” to “soft” all the time – unless that’s the point)
  • Try to vary the melody just a little bit – the brain, a very good pattern matching machine feels “engaged” with subtle variety. I read somewhere (don’t remember the source) long time ago that classic compositions usually start with a pattern that rarely (if ever) repeats in its original form until the end, thus keeping the brain engaged “looking for the right pattern”.
    • Make different by not completing – for example, start with half the melody and then add more of it as the song progresses or vice versa (or just skip/add tones as appropriate)
    • Make different by slight changes – changing a note here and there can add enough difference to make the music a whole lot interesting. For comparison with Silverlight, imagine having an animation of a rectangle going back and forth for 10 seconds. Now imagine another animation that builds on top of the first by changing the shape of the rectangle towards circle slightly form time to time. Which one would you be more likely to watch longer?

Skills

Piano playing is like software development (which is like RPG games). Thus, piano playing is like RPG games.

For example, you can use C++, but you may use only it’s “C” part (not the object oriented aspects). Thus learning object-oriented programming is a skill (like in RPG “Fireball Level 3” would be a skill). Piano is the same – you can press the keys but by learning skills you can advance your character level.

Here I will define 3 classes that can be useful to think about when starting with piano:

  • Pianist: master of piano skill and live performances
  • Bard: a great singer (alone or in choir) with good command of an instrument
  • Synthetron: master of computers and synthesizers capable of producing a complete score with many instruments, part by part. May not be necessarily good with live performances though.

There are also 2 life-paths available:

  • Performer
  • Composer

For example, you can be a Pianist Composer or a Bard Performer! :)

Here’s a list of few not-so-obvious skills (at least for me) that can bring you to the next level. Search on the web to find our how to improve those if you’re interested:

  • Relative Pitch: Allows you to name any note in relation to another. For example if someone plays C and tell you it’s C. Then plays E, and you can tell that it’s E, since you can tell how much the second note played was apart from the first. Must-have for the Bard class and overall very good to posess for Pianist and Synthethron too. Choirs tend to “sag” in pitch so having a good relative pitch allows you to sing along.
  • Absolute Pitch: (1) Allows you to name any note when played. (2) Allows you to sing any note (provided you can sing) when named. This is a 2-blade skill, since choirs and pianos go down or “sag” in pitch over time. Then they might sound weird to you. Thus I would apply this skill to Synthetrons or Pianists in possession of electric piano (since these don’t sag in pitch). The big plus is that you can compose music in your head and “hear” music by reading – cool huh? :)
  • Autonomous Hand Control: The name of this implies this skill would be useful for the Synthetron class, although it’s most useful for the Pianist. Having good separate control over both your left and right hand when playing allows you to put your left hand on “auto-pilot” (accompaniment mode) while thinking up a melody with the right hand. Also helps with some of the techniques (such as speeding or slowing down a melody with one hand only).

Obviously, you can expand the list of classes, paths and skills more – I’m interested to hear what people would come by.

Major Cheats for Beginners:

  • Overlaying strings over piano (even cheap keyboards nowadays have this), makes mistakes pop out much less
  • Many other cheats in the http://pianoforall.com/ books (like ballad based on pentatonic scale, where you can hit any note from a huge selection, in any order and it sounds good). These tricks are explained there…
  • I think there’s no need to always try to follow books and tutorials. Take the best of them and move on. For example, I paid very little attention to proper hand posture (after reading that my hands should be “like holding an apple”). My hands were stiff but after 2 weeks they feel lot more smooth and natural without any effort to keep the posture (if you don’t, your fingers start to hurt and the sounds are not so nice so it’s a self-fixing issue:)
  • Youtube is an amazing source of techniques you can use later in composing

Here are a few:

 

Also some of the master’s works:

This one from ear with lots of improvising based on music from Transformers:

Another interpretation by ear of the same song:

Official Soundtrack to New Moon (The Meadow):

Hope you like it! Please comment!

Simple Functions for HTML Interop

Apr 3, 2010

I used the below functions on several occasions to transfer data between a server and Silverilght application.

The blog integration between .NET Blog Engine and my Silverlight navigation on top of this site is done using this method.

You can see the blog title “You Had Me At Hello World” in the Silverlighg navigation window on top.

The interop is easy and I tried it in IE, Firefox, Chrome, Opera. Define an HTML like this:


<span style="visibility: hidden; display: none; height: 0px; width: 0px; border: 0px">
    <span id="titleText">You Had Me At 'Hello World!'</span>
    <span id="titleLink">http://nokola.com/blog/</span>
    <span id="titleDescription">Coding and Special Effects for Silverlight</span>
</span>

And then use the functions from within your Silverlight app like this:

HtmlDocument doc = HtmlPage.Document;
string str = doc.GetTextFromHtmlPage("titleText", "nokola.com");
string uriString = doc.GetTextFromHtmlPage("titleLink", "">http://nokola.com");
string str3 = doc.GetTextFromHtmlPage("titleDescription", null);

Nothing fancy, but works :)

Here’s the source:

using System.Windows.Browser;

namespace EasyPainter
{
    /// <summary>
    /// Common functions for HTML interop
    /// </summary>

    public static class HtmlDocumentExtensions
    {
        /// <summary>
        /// Retrieves the text contents of a given HTML element by ID
        /// Sample html:
        ///    <span style="visibility: hidden; display: none; height: 0px; width: 0px; border: 0px">
        ///        <span id="titleText">You Had Me At 'Hello World!'</span>
        ///    </span>
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="elementId"></param>
        /// <returns></returns>

        public static string GetTextFromHtmlPage(this HtmlDocument doc, string elementId)
        {
            HtmlElement elementById = doc.GetElementById(elementId);
            if (elementById != null)
            {
                object property = elementById.GetProperty("innerText");
                if (property != null)
                {
                    return property.ToString();
                }
                property = elementById.GetProperty("textContent");
                if (property != null)
                {
                    return property.ToString();
                }
            }
            return null;
        }

        /// <summary>
        /// Retrieves the text contenst of HTML element by ID with a default value
        /// in case the element is missing or empty
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="elementId"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>

        public static string GetTextFromHtmlPage(this HtmlDocument doc, string elementId, string defaultValue)
        {
            string textFromHtmlPage = doc.GetTextFromHtmlPage(elementId);
            if (string.IsNullOrEmpty(textFromHtmlPage))
            {
                return defaultValue;
            }
            return textFromHtmlPage;
        }
    }

}

EasyPainter: Cloud Turbulence and Particle Buzz

Apr 2, 2010

Two new effects for EasyPainter with source code!

Cloud Turbulence: works great on clouds, but not much anything else I tried (OK on metal – makes it look like liquid).

Before:

CloudsBefore

After:

CloudsAfter

Particle Buzz

This effect has a lot of potential, since it’s the first displacement effect in EasyPainter based on image. Currently, it just uses random noise (Random.Next(256) for the R,G,B and 255 for the A channels).

buzz_before

buzz_after

Using other images (such as pencil strokes, grass, etc) for displacement yields very nice results! I’m still experimenting :)

Source Code

Particle Buzz. The noise is a 256x256 texture initialized to random values and remember to set this.DdxUvDdyUvRegisterIndex = 1; when initializing the shader in code behind.

sampler2D Noise : register(S1);

/// <summary>Width of the input.</summary>
/// <minValue>2</minValue>
/// <maxValue>100</maxValue>
/// <defaultValue>30</defaultValue>
float Shake : register(C0);

/// <summary>Input size</summary>
/// <type>Size</type>
/// <minValue>10,10</minValue>
/// <maxValue>100,100</maxValue>
/// <defaultValue>#01000000</defaultValue>
float4 dxdyShift : register(c1);

/// <summary>Input size</summary>
/// <type>Size</type>
/// <defaultValue>1024,768</defaultValue>
float2 ImageSize : register(C2);

//--------------------------------------------------------------------------------------
// Sampler Inputs (Brushes, including ImplicitInput)
//--------------------------------------------------------------------------------------

sampler2D Input : register(S0);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float2 dx = dxdyShift.xy;
    float2 dy = dxdyShift.zw;
    float4 noiseValue = tex2D(Noise, frac(2*uv*(ImageSize/256.0)));
    noiseValue -= 0.5;
    noiseValue *= Shake;
    return tex2D(Input, saturate(uv+(dx+dy)*noiseValue.rb));
}

Cloud Turbulence

Needs this.DdxUvDdyUvRegisterIndex = 1; too.

/// <summary>Width of the input.</summary>
/// <minValue>2</minValue>
/// <maxValue>100</maxValue>
/// <defaultValue>30</defaultValue>
float Shake : register(C0);

/// <summary>Input size</summary>
/// <type>Size</type>
/// <minValue>10,10</minValue>
/// <maxValue>100,100</maxValue>
/// <defaultValue>#01000000</defaultValue>
float4 dxdyShift : register(c1);

sampler2D Input : register(S0);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    //pixel step vectors
    float2 dx = dxdyShift.xy;
    float2 dy = dxdyShift.zw;
    float4 noiseValue = tex2D(Input, uv);
    noiseValue.rg = float2((noiseValue.r + noiseValue.b/4), noiseValue.g + noiseValue.r/2);
    noiseValue -= 0.5;
    noiseValue *= Shake;
    return tex2D(Input, saturate(uv+(dx+dy)*noiseValue.rg));
}

Hope you like it! :)

EasyPainter Source Pack 3: Adorners, Mouse Cursors and Frames

Mar 17, 2010

Adorners went a long way since their first release few months ago.

They integrate with zoom now, have more options for controlling functionality and can use a shared "cursor plane" for displaying mouse cursors consistently across your application. Extensibility is improved allowing definition of custom adorner frames. There are 7 custom cursors and 4 custom frames to get you started :)

Download source code

I use the same adorner implementation in EasyPainter.

Here's a live demo with different adorner frame for each image:

Features

  • Custom, Extensible Mouse Cursors allow you to use the system or your own mouse cursors even if you don't use the adorner functionality. See CursorPlane.cs for more info

The custom cursors support:

    • Size (for example, bigger cursor for bigger brush size)
    • Rotation (used to make the resize cursor perpendicular to the adorner frame)

The current list supports all system cursors as well as these:

Size, // Size cursor that supports angle
Rotate, // Rotate cursor supporting angle
Move, // Move cursor
Brush, // Brush cursor, supports size
SelectionBrush, // Selection brush cursor
Crosshair, // Crosshair cursor - like the one used on snipers or in image editing programs to pinpoint that pixel
MarkerSelect, // Cursor used to select a marker on the surface (e.g. used to select point for applying origin for zoom blur effect)

To use the cursors you have to set up a cursor plane in XAML:

<adorners:CursorPlane Name='cursorPlane' />

And then initialize it in code-behind:

    InitializeComponent();
    ctlCursorPlane.SetSystemCursorElement(frameRoot);

The frameRoot specifies which control will display the cursors. For example, in EasyPainter the Crop adorner spans only the image (the adorner is parented to a different parent than the cursor plane), but the rotate/resize cursor go outside of the image. The frameRoot is used to calculate the offsets so that the adorners (or someone else using the cursor plane) can account for the different parents and draw the cursors at the correct locations on screen.

  • Customizable Adorners with extensible adorner frames

You can now define your custom adorner frames by creating a UserControl and implementing the functionality you need from the IAdornerFrame interface.

There are 4 existing frames currently: AnimatedRectangleFrame, CropFrame, GlassFrame and PointFrame. The last one is just a dot being used to specify locations of effects in EasyPainter – e.g. Zoom motion effect.

The existing frames can be zoom-aware. For example the CropFrame displays the correct image width and height in the top-left corner regardless of zoom.

/// Represents an adorner frame, e.g. glass border
public interface IAdornerFrame {
    /// Called when the frame is attached to adorner
    void Attached();

    /// Called when the frame is detached from adorner
    void Detached();

    /// Sets the zoom level for this adorner frame. The zoom level is used by the frame to display correct coordinates (e.g. Width and Height)
    void SetZoom(double newZoomLevel);

    void SizeChanged(double newWidth, double newHeight);
}

  • More adorner options: bool CanRotate, CanResize, CanMove, void SetBounds(x, y, width, height), SetZoom(double zoomLevel) allow you to change adorner capabilities, restrict it to specific area, and make it zoom-aware

I didn't have time to add the behaviours back since I don't use those yet and I'm mainly using Visual Studio for development. If anyone is interested in porting these over to the current version Andrej Tozon created the Behaviours for the original version. Here's a link to his version. Thanks Andrej!

The source code is licensed under MS-PL.

Pictures are licensed under the following Creative Commons License: http://creativecommons.org/licenses/by/2.0/
Picture locations:
http://www.flickr.com/photos/proimos/3954987905/
http://www.flickr.com/photos/proimos/4300827122/
http://www.flickr.com/photos/tenioman/2771903123/

Hope you like it! Please comment!

    

EasyPainter Source Pack 2: Flickr, ComboCheckBox and more!

Mar 11, 2010

Yes! EasyPainter Source Pack 2 is here!

This source pack contains Flickr integration sample amongst other also important things (read below).

Download Source Code

The live demo:

Usage

  1. Go to http://www.flickr.com/services/api/, sign up and get an API key for your app
  2. Put the key in Flickr\FlickrHelper.cs
  3. Use the below code behind and XAML:

public MainPage() {
    InitializeComponent();
    Globals.ToolbarRadioButtonStyle = (Style)Application.Current.Resources["ToolbarRadioButton"];
    IGenericUserInterface ui = (IGenericUserInterface)openDialog1;
    ui.Result += new GenericResultHandler(ui_Result);
}

void ui_Result(IGenericUserInterface sender, EasyPainter.Imaging.ResultType result, bool uiDismissed) {
    MessageBox.Show(String.Format("Result type: {0}\nPhoto Url: {1}", result, openDialog1.PhotoUrl));
}

XAML:

<Grid x:Name="LayoutRoot" Background="White">
    <my:OpenDialog x:Name='openDialog1' />
</Grid>

License

The source code of the sample is licensed under MS-PL

Flickr usage is governed by their own license: check the terms of use on http://www.flickr.com/services/api/ for more details.

Source Code Information

Apart from Flickr, there are some other things interesting to developers in this sample:

  • Queuing for WebClient. The WebClient class does not allow to call DownloadStringAsync() while another download using WebClient is in progress. The WebClientQueue class in the sample allows you to queue work items, cancel them, gracefully display and recover from errors and get updates on progress.
  • Caching for WebClient REST API and other requests. The current cache is set in WebClientQeueue to 5 minutes. Huge speed improvement when browsing through the images!
  • ComboCheckBox control (far from perfect, but still usable for some cases)
  • Minimalistic WrapPanel. The 10KB version of the WrapPanel extracted from the Silverlight toolkit that is typically around 280 KB.
  • Lightweight XML parsing. Using XMLReader instead of Linq like other samples do helps shave off about 100KB of size from the sample
  • Small size! Combining the 2 above items, and the XAP file is only 27K (I wish it was less but life if life :))
  • ImageList control for showing and paging through images
  • ImageSwitchHelper – a "fit-and-finish" control that helps avoid "jumping" when the image on the right changes. The control preserves the frame size until the next image is loaded.
  • An easy way to keep UI alive and preserve the dialog view (DialogStore.cs). If you open EasyPainter you'll notice that every time you click "Open from Flickr" you will go to your previous view instead of resetting the UI.
  • IUserInterface – a kind of generic interface for reusable UIs and for connecting UIs with other parts of your program. This interface is used in all dialogs in EasyPainter, for example to update the view when filter values change. It also allows to click through effects without clicking Cancel on each dialog (for example). All EasyPainter filter UI dialogs are built on-the-fly from metadata info assigned to the filter (this would come in another sample sometime).

I almost missed something important: once you have the image Url, you can display it in an Image tag. If you want to use it from within WriteableBitmap though, you'll have to round-trip it through the server that serves the .xap file (in EasyPainter's case that's www.nokola.com).

Also note that Source Pack 1 has a refresh today too containing new features and bug fixes!

I hope this sample will help you make more responsive/pleasing UIs in addition to Flickr!

Hope you like it! Please comment :)

  

EasyPainter Source Pack 1 Refresh

Mar 11, 2010

There were several major bugfixes in EasyPainter controls and few updates.

Here are the main two:

  • Changing the color the first time when using the API in the color picker now works (heh :)).
  • Editable slider has a new DisplayFormat property allowing you to override the format (e.g. DisplayFormat="X: 0.0" – see below)

The sample is also moved to Visual Studio 2010 RC.

Here is a refresh of source pack 1 with the changes:

Download Source Code

The live demo:

EasyPainter: Lion Hair styling

Mar 5, 2010

I am playing with EasyPainter recently :) There are no new additions to the software (yet).

Here's how to apply a hair style to a lion.

Original:

lions

Hair styled:

Lions_after

The original image is from: http://www.flickr.com/photos/wwarby/2404544591/ (search for "lion" in EasyPainter)

I'd say the second one looks way cooler, especially with the blue Raiden-like eyes. Raiden is the god of thunder from Mortal Kombat!

Effects used: Color shift for the eyes, followed by Brigthness. Waves for the "hair" and a finishing touch of Life-like.

  

nokola.com | Terms | Log in

Recent

About the author

Happy & enjoying life. Software enthusiast.
The opinions I express here and on nokola.com are mine and not my employeer's (Microsoft).
This is the official blog of nokola.com. You can find Silverlight samples, coding stuff, and hopefully other interesting things here.