//Applies the current special effect and stores it private void ApplyEffect() { if (SpecialEffect == null) { EffectImage = null; return; } BitmapSource b = null; int[] sourceImagePixels = null; int sourceWidth = -1; int sourceHeight = -1; Dispatcher.Invoke(DispatcherPriority.Normal, new DispatcherOperationCallback(delegate(object arg) { BitmapSource bitmap = SourceImage; sourceWidth = bitmap.PixelWidth; sourceHeight = bitmap.PixelHeight; sourceImagePixels = new int[sourceWidth * sourceHeight * 4]; bitmap.CopyPixels(sourceImagePixels, sourceWidth * 4, 0); return(null); } ), null); if (sourceWidth < 0 || sourceHeight < 0 || sourceImagePixels == null) { return; } //Clone so that this thread owns the image b = BitmapSource.Create(sourceWidth, sourceHeight, 96, 96, PixelFormats.Bgra32, null, sourceImagePixels, sourceWidth * 4); b = SpecialEffect.ExecuteFilter(b); //It is necessary to pass the pixels raw between threads // to avoid cross thread calls to wpf objects int[] p = new int[b.PixelWidth * b.PixelHeight]; b.CopyPixels(p, b.PixelWidth * 4, 0); int width = b.PixelWidth; int height = b.PixelHeight; PixelFormat format = b.Format; Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(delegate(object arg) { EffectImage = BitmapSource.Create(width, height, 96, 96, format, null, p, width * 4); return(null); } ), null); }