Wet floor effect batch transform using WPF
My wife just took some new photos for her scrapbooking website. I have a coverflow effect on that page, so I needed to apply the wet floor transform to 64 images. Rather than do it all by hand, I wrote some WPF code to do it for me:
public class WetFloor { public static void Render(string source, string target, int targetWidth) { using (Stream input = File.OpenRead(source)) { // Load the source jpg. JpegBitmapDecoder sourceJpg = new JpegBitmapDecoder(input, BitmapCreateOptions.None, BitmapCacheOption.Default); if (sourceJpg.Frames.Count != 1) throw new Exception(String.Format("I don't know how to handle {0} frames.", sourceJpg.Frames.Count)); BitmapFrame sourceBitmap = sourceJpg.Frames[0]; // Create a render target scaled to 400 pixels at 150% the aspect ratio. double scale = (double)targetWidth / sourceBitmap.PixelWidth; RenderTargetBitmap renderTarget = new RenderTargetBitmap( targetWidth, (int)Math.Round(scale * (float)sourceBitmap.PixelHeight * 1.5), sourceBitmap.DpiX, sourceBitmap.DpiY, PixelFormats.Pbgra32); // Paint a rectangle with the source bitmap. Rectangle original = new Rectangle() { Fill = new ImageBrush(sourceBitmap), Width = scale * sourceBitmap.Width, Height = scale * sourceBitmap.Height }; original.Arrange(new Rect(new Size(scale * sourceBitmap.Width, scale * sourceBitmap.Height))); renderTarget.Render(original); // Paint a black rectangle. Rectangle shade = new Rectangle() { Fill = new SolidColorBrush(Colors.Black), Width = scale * sourceBitmap.Width, Height = scale * sourceBitmap.Height }; shade.Arrange(new Rect(new Point(0, scale * sourceBitmap.Height), new Size(scale * sourceBitmap.Width, scale * sourceBitmap.Height))); renderTarget.Render(shade); // Paint an inverted rectangle with the source bitmap. Border reflection = new Border() { Background = new ImageBrush(sourceBitmap), Width = scale * sourceBitmap.Width, Height = scale * sourceBitmap.Height, RenderTransform = new ScaleTransform(1.0f, -1.0f, scale * sourceBitmap.Width / 2, scale * sourceBitmap.Height / 2), OpacityMask = new LinearGradientBrush() { StartPoint = new Point(0, 1), EndPoint = new Point(0, 0), GradientStops = new GradientStopCollection(new GradientStop[] { new GradientStop() { Offset = -0.3f, Color = Colors.Black }, new GradientStop() { Offset = 0.5f, Color = Colors.Transparent } }) } }; reflection.Arrange(new Rect(new Point(0, scale * sourceBitmap.Height), new Size(scale * sourceBitmap.Width, scale * sourceBitmap.Height))); renderTarget.Render(reflection); // Render the final product. JpegBitmapEncoder png = new JpegBitmapEncoder(); png.Frames.Add(BitmapFrame.Create(renderTarget)); using (Stream fs = File.Create(target)) { png.Save(fs); } } } }
Enjoy.