private int GenerateStrokesWithRawScaling(Bitmap input, ColorImage area, ArrayList list, int S, int factor, int level) { int x, y; System.Console.WriteLine("Generating stroke positions image."); /* * Bitmap areascaled = new Bitmap(area.Width / factor, area.Height / factor); * Graphics g = Graphics.FromImage(areascaled); * g.ScaleTransform(1.0f / (float)factor, 1.0f / (float)factor); * g.DrawImage(area, 0, 0, area.Width, area.Height); * areascaled.Save("areascaled-" + factor.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); * ColorImage img = new ColorImage(areascaled); */ ColorImage scaledWidth = ColorImage.ScaleWidth(area, area.Width / factor); ColorImage img = ColorImage.ScaleHeight(scaledWidth, area.Height / factor); this.dither = new FloydSteinbergDither(4 * S / System.Math.Sqrt(level), 2.0f / level); UnsafeBitmap dithered = new UnsafeBitmap(this.dither.Dither(img)); //StatusReporter.Instance.SubmitWorkingImage(ImageTools.GenWorkingImage(dithered)); //dithered.Save("dithered-" + factor.ToString() + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp); Bitmap inscaled = new Bitmap(input.Width / factor, input.Height / factor); Graphics g2 = Graphics.FromImage(inscaled); g2.ScaleTransform(1.0f / (float)factor, 1.0f / (float)factor); g2.DrawImage(input, 0, 0, input.Width, input.Height); //inscaled.Save("inputscaled-" + factor.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); System.Console.WriteLine("Collecting strokes."); int maxY = dithered.Height; int maxX = dithered.Width; ColorImage inScaled = new ColorImage(new UnsafeBitmap(inscaled)); // should be &inputscaled for (y = 0; y < maxY; y++) { for (x = 0; x < maxX; x++) { if (dithered.GetPixel(x, y).R == 0) { //StatusReporter.Instance.SubmitWorkingImage(ImageTools.GenWorkingImage(dithered, x, y, S, S)); Stroke s = GenerateStroke(inScaled, x, y, S, factor, level); list.Add(s); } } } return(list.Count); }
public Bitmap Render(ArrayList strokes, Bitmap paintingBitmap) { ColorImage strokeImage = new ColorImage(new UnsafeBitmap(strokeBitmap)); int strokeCount = 0; Graphics gr = Graphics.FromImage(paintingBitmap); gr.Clear(System.Drawing.Color.White); ColorImage painting = new ColorImage(new UnsafeBitmap(paintingBitmap)); double OneEightyOverPi = 180.0f / System.Math.PI; Hashtable scaledStrokeHash = new Hashtable(); Hashtable scaledWidthHash = new Hashtable(); TimeSpan durationGDI = TimeSpan.Zero; TimeSpan durationBlending = TimeSpan.Zero; TimeSpan durationScaling = TimeSpan.Zero; DateTime start = DateTime.Now; foreach (Stroke stroke in strokes) { double radians = stroke.theta * -1.0; //int max = System.Math.Max((int)stroke.l, (int)stroke.w); if ((float.IsNaN(stroke.l)) || (float.IsNaN(stroke.w))) { continue; } int scaledWidth = (int)stroke.l; int scaledHeight = (int)stroke.w; if ((scaledWidth == 0) || (scaledHeight == 0)) { continue; } DateTime startScaling = DateTime.Now; Point p = new Point(scaledWidth, scaledHeight); Bitmap newStrokeBmp = null; if (scaledStrokeHash.ContainsKey(p)) { newStrokeBmp = (Bitmap)scaledStrokeHash[p]; } else { ColorImage temp1; if (scaledWidthHash.ContainsKey(scaledWidth)) { temp1 = (ColorImage)scaledWidthHash[scaledWidth]; } else { temp1 = ColorImage.ScaleWidth(strokeImage, scaledWidth); scaledWidthHash[scaledWidth] = temp1; } temp1 = ColorImage.ScaleWidth(strokeImage, scaledWidth); ColorImage scaledImage = ColorImage.ScaleHeight(temp1, scaledHeight); newStrokeBmp = scaledImage.GenerateBitmap(); scaledStrokeHash[p] = newStrokeBmp; } durationScaling += DateTime.Now - startScaling; DateTime startGDI = DateTime.Now; Bitmap sbmp = new Bitmap(newStrokeBmp.Width, newStrokeBmp.Height); Graphics g = Graphics.FromImage(sbmp); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;// HighQualityBicubic; g.TranslateTransform(-newStrokeBmp.Width / 2, -newStrokeBmp.Height / 2, System.Drawing.Drawing2D.MatrixOrder.Append); g.RotateTransform((float)(radians * OneEightyOverPi), System.Drawing.Drawing2D.MatrixOrder.Append); g.TranslateTransform(newStrokeBmp.Width / 2, newStrokeBmp.Height / 2, System.Drawing.Drawing2D.MatrixOrder.Append); g.DrawImage(newStrokeBmp, 0, 0, newStrokeBmp.Width, newStrokeBmp.Height); //sbmp.Save("newstroke" + stroke.theta.ToString() + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); sbmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); Color c = Color.FromArgb(stroke.red, stroke.green, stroke.blue); durationGDI += DateTime.Now - startGDI; DateTime startBlending = DateTime.Now; ColorImage.Blend(ref painting, new ColorImage(new UnsafeBitmap(sbmp)), c, stroke.xc, stroke.yc); durationBlending += DateTime.Now - startBlending; //painting.GenerateBitmap().Save("intermediate-" + strokeCount + "n.jpg", System.Drawing.Imaging.ImageFormat.Jpeg); strokeCount++; //StatusReporter.Instance.SetPercentComplete((int)(((float)strokeCount / (float)(strokes.Count)) * 100.0)); } /* * foreach (Point p in h.Keys) * { * Console.WriteLine("Stroke size (" + p.X + "," + p.Y + ") = " + (int)h[p]); * } */ TimeSpan duration = DateTime.Now - start; StatusManager.Instance.StatusMessage("Total GDI duration: " + durationGDI.TotalMilliseconds + "ms"); StatusManager.Instance.StatusMessage("Total Scaling duration: " + durationScaling.TotalMilliseconds + "ms"); StatusManager.Instance.StatusMessage("Total Blending duration: " + durationBlending.TotalMilliseconds + "ms"); StatusManager.Instance.StatusMessage("Rendering duration: " + duration.TotalMilliseconds + "ms"); //bmp.Save("newpainting.jpg", System.Drawing.Imaging.ImageFormat.Jpeg); return(painting.GenerateBitmap());; }