private static bool ProcessArgs(ref Movement movement, IList <string> strs) { if (strs.Count == 0) { return(false); } movement.EndX = (int)Position.Center; movement.EndY = (int)Position.Center; movement.Filename = null; movement.Height = 0; movement.SmoothEnd = 0f; movement.SmoothStart = 0f; movement.StartX = (int)Position.Center; movement.StartY = (int)Position.Center; movement.Width = 0; movement.ZoomEnd = 1f; movement.ZoomEndCode = (int)ZoomCode.None; movement.ZoomStart = 1f; movement.ZoomStartCode = (int)ZoomCode.None; var actiondata = false; var continued = false; for (var i = 0; i < strs.Count; i++) { var str = strs[i]; string[] location; int h; int w; int x; int y; float f; switch (str.ToLowerInvariant()) { case @"geometry": case @"resize": case @"resolution": case @"size": if (i == strs.Count) { continue; } i++; str = strs[i]; var dimensions = Regex.Split(str, @"[:x]"); if (dimensions.Length < 2) { continue; } if (!int.TryParse(dimensions[0], out w) || !int.TryParse(dimensions[1], out h)) { continue; } if ((w < 1) || (h < 1)) { continue; } _outputWidth = w; _outputHeight = h; break; case @"owidth": case @"outputwidth": case @"width": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!int.TryParse(str, out w) || w <= 0) { continue; } _outputWidth = w; break; case @"height": case @"oheight": case @"outputheight": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!int.TryParse(str, out h) || h <= 0) { continue; } _outputHeight = h; break; case @"sharpness": if (i == strs.Count) { continue; } i++; str = strs[i]; int s; if (!int.TryParse(str, out s) || s <= 0) { continue; } _sharpness = s; break; case @"pansmoothness": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!float.TryParse(str, out f)) { continue; } if (f < 0.0) { f = 0f; } if (f > 0.5) { f = 0.5f; } _panSmoothRatio = f; break; case @"zoomsmoothness": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!float.TryParse(str, out f)) { continue; } if (f < 0.0) { f = 0f; } if (f > 0.5) { f = 0.5f; } _zoomSmoothRatio = f; break; case @"jpegquality": case @"jpgquality": case @"quality": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!int.TryParse(str, out h) || h <= 0) { continue; } _jpegQuality = h; break; case @"fps": case @"framerate": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!float.TryParse(str, out f) || f <= 0) { continue; } _framerate = f; break; case @"output": case @"outputtype": case @"type": if (i == strs.Count) { continue; } i++; str = strs[i]; if (str.Equals(@"jpeg", StringComparison.OrdinalIgnoreCase) || str.Equals(@"jpg", StringComparison.OrdinalIgnoreCase)) { _outputFormat = OutputFormat.JPG; } else if (str.Equals(@"ppm", StringComparison.OrdinalIgnoreCase)) { _outputFormat = OutputFormat.PPM; } break; case @"backgroundcolor": case @"bgcolor": case @"defaultcolor": if (i == strs.Count) { continue; } i++; str = strs[i].Replace(@"#", string.Empty); int c; if (!int.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat, out c)) { continue; } _defaultColor = Pixel.FromArgb(c); break; case @"img": if (i == strs.Count) { continue; } i++; str = strs[i]; movement.Filename = str; _image = OpenImage(str, true); movement.Height = _image.Height; movement.Width = _image.Width; actiondata = true; break; case @"crossfade": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!float.TryParse(str, out f) || f <= 0) { continue; } movement.Duration = f; movement.Crossfade = (int)(f * _framerate) - 2; if (_frameCount < movement.Crossfade) { movement.Crossfade = _frameCount; } _frameCount -= movement.Crossfade; movement.CrossFrames = movement.Crossfade; break; case @"startpoint": if (i == strs.Count) { continue; } i++; str = strs[i]; location = str.Split(','); if (!int.TryParse(location[0], out x) || x < 0) { movement.EndX = movement.EndY = movement.StartX = movement.StartY = Translate(location[0]); continue; } if (!int.TryParse(location[1], out y) || y < 0) { continue; } movement.StartX = x; movement.EndX = x; movement.StartY = y; movement.EndY = y; actiondata = true; break; case @"endpoint": if (i == strs.Count) { continue; } i++; str = strs[i]; location = str.Split(','); if (!int.TryParse(location[0], out x) || x < 0) { movement.EndX = movement.EndY = Translate(location[0]); continue; } if (!int.TryParse(location[1], out y) || y < 0) { continue; } movement.EndX = x; movement.EndY = y; actiondata = true; break; case @"zoom": if (i == strs.Count) { continue; } i++; str = strs[i]; var zoom = str.Split(','); if (zoom.Length == 2) { if (float.TryParse(zoom[0], out f)) { movement.ZoomStart = f; } else { movement.ZoomStart = 0; movement.ZoomStartCode = (ZoomCode)Translate(zoom[0]); } if (float.TryParse(zoom[1], out f)) { movement.ZoomEnd = f; } else { movement.ZoomEnd = 0; movement.ZoomEndCode = (ZoomCode)Translate(zoom[1]); } } else { if (continued) { if (float.TryParse(zoom[0], out f)) { movement.ZoomEnd = f; } else { movement.ZoomEnd = 0; movement.ZoomEndCode = (ZoomCode)Translate(zoom[0]); } } else { if (float.TryParse(zoom[0], out f)) { movement.ZoomStart = f; movement.ZoomEnd = f; } else { movement.ZoomStart = 0; movement.ZoomEnd = 0; var code = Translate(zoom[0]); movement.ZoomEndCode = (ZoomCode)code; movement.ZoomStartCode = (ZoomCode)code; } } } actiondata = true; break; case @"duration": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!float.TryParse(str, out f) || f <= 0) { continue; } movement.Duration = f; actiondata = true; break; case @"startsmooth": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!float.TryParse(str, out f) || f <= 0) { continue; } movement.SmoothStart = f; actiondata = true; break; case @"endsmooth": if (i == strs.Count) { continue; } i++; str = strs[i]; if (!float.TryParse(str, out f) || f <= 0) { continue; } movement.SmoothEnd = f; actiondata = true; break; case @"continue": continued = true; movement.EndX = movement.StartX = _lastMovement.EndX; movement.EndY = movement.StartY = _lastMovement.EndY; movement.Filename = _lastMovement.Filename; movement.Height = _lastMovement.Height; movement.Width = _lastMovement.Width; movement.ZoomEnd = movement.ZoomStart = _lastMovement.ZoomEnd; actiondata = true; break; default: Console.WriteLine("Unknown command: {0}", str); break; } } if (actiondata) { Normalize(ref movement); _lastMovement = movement; return(true); } return(false); }
private static void Frame(ref Movement movement, float x, float y, float z) { var crossdata = new Pixel[0]; if (_lastResizeX == -1) { _lastFilename = string.Empty; } // Calculate Resize float fx = movement.Width; fx *= z; var resizeX = (int)fx; if (resizeX < _outputWidth) { resizeX = _outputWidth; } float fy = movement.Height; fy *= z; var resizeY = (int)fy; if (resizeY < _outputHeight) { resizeY = _outputHeight; } // Calculate Crop fx = x * z; var cropX = (int)fx; cropX -= _outputWidth / 2; if (cropX < 0) { cropX = 0; } fy = y * z; var cropY = (int)fy; cropY -= _outputHeight / 2; if (cropY < 0) { cropY = 0; } var path = string.Format("{0}{1}{2:D5}.{3}", _tmpdir, Path.DirectorySeparatorChar, _frameCount, _outputFormat.ToString().ToLowerInvariant()); _image = OpenImage(movement.Filename, true); Console.Write(@"Creating frame #{0} at x={1:0.00} y={2:0.00} and zoom {3:0.00}", _frameCount, x, y, z); var stopWatch = new Stopwatch(); stopWatch.Start(); var ppm = _fastRender ? ResizeFast(_image, x, y, z) : Resize(_image, x, y, z); stopWatch.Stop(); Console.WriteLine(@" {0}", stopWatch.ElapsedMilliseconds); if (movement.Crossfade > 0) { var crossedjpg = OpenImage(path, false); crossdata = crossedjpg.Pixels; } if (crossdata.Length > 0) { var bytecount = _outputWidth * _outputHeight; float ratioA = movement.Crossfade; float ratioB = movement.CrossFrames; ratioA /= ratioB; ratioB = 1 - ratioA; for (var i = 0; i < bytecount; i++) { var valueA = crossdata[i]; var valueB = ppm[i]; var mixedvalue = ppm[i]; mixedvalue.R = (byte)(valueA.R * ratioA + valueB.R * ratioB); mixedvalue.G = (byte)(valueA.G * ratioA + valueB.G * ratioB); mixedvalue.B = (byte)(valueA.B * ratioA + valueB.B * ratioB); ppm[i] = mixedvalue; } movement.Crossfade--; } else { movement.Crossfade = 0; movement.CrossFrames = 0; } var res = new Image { Height = _outputHeight, Path = path, Pixels = ppm, Width = _outputWidth }; if (_showOutput) { ShowImage(res); } if (_outputFormat == OutputFormat.JPG) { WriteJPG(res, path); } else { PPM.Write(res, path); } if (!movement.Filename.Equals(_lastFilename, StringComparison.Ordinal) || _lastResizeX != resizeX || _lastResizeY != resizeY || _lastCropX != cropX || _lastCropY != cropY) { _lastFilename = movement.Filename; _lastResizeX = resizeX; _lastResizeY = resizeY; _lastCropX = cropX; _lastCropY = cropY; } _frameCount++; }
private static Pixel[] ResizeNoBlur(Image image, float x, float y, float z) { var bufsize = _outputWidth * _outputHeight; var res = new Pixel[bufsize]; for (var i = 0; i < bufsize; i++) { res[i] = _defaultColor; } float fw = image.Width; float frw = _outputWidth; float frh = _outputHeight; var aaRadius = fw / (frw * z * _sharpness); if (aaRadius < 1.33333) { aaRadius = 1.33333f; } var aaRadiusSquared = aaRadius * aaRadius; CheckPrevBuffer(_outputWidth, _outputHeight); var pprev = 0; for (var iy = 0; iy < _outputHeight; iy++) { float fry = iy; var deltaY = y - fw * frh / (z * 2.0f * frw) + fry * fw / (frw * z); var fstarty = deltaY - aaRadius; var fendy = deltaY + aaRadius; var istarty = (int)fstarty; var iendy = (int)fendy; for (var ix = 0; ix < _outputWidth; ix++) { float frx = ix; var deltaX = x - fw / (z * 2.0f) + frx * fw / (frw * z); var fstartx = deltaX - aaRadius; var fendx = deltaX + aaRadius; var istartx = (int)fstartx; var iendx = (int)fendx; if (_motionBlur) { _prev[pprev] = new Point((int)deltaX, (int)deltaY); pprev++; } var fred = 0f; var fgreen = 0f; var fblue = 0f; var ftotalweight = 0f; for (var i = istarty; i <= iendy; i++) { if ((i < 0) || (i >= image.Height)) { continue; } float fi = i; for (var j = istartx; j <= iendx; j++) { if ((j < 0) || (j >= image.Width)) { continue; } float fj = j; var angularDistanceSquared = (fj - deltaX) * (fj - deltaX) + (fi - deltaY) * (fi - deltaY); if (aaRadiusSquared - angularDistanceSquared <= 0.0) { continue; } var angularDistance = (float)Math.Sqrt(angularDistanceSquared); //if (aaRadius - angularDistance <= 0.0) // continue; var fweight = aaRadius - angularDistance > 0.001 ? aaRadius - angularDistance : 0.001f; ftotalweight = ftotalweight + fweight; var inOffset = i * image.Width + j; var inputPixel = image.Pixels[inOffset]; fred += inputPixel.R * fweight; fgreen += inputPixel.G * fweight; fblue += inputPixel.B * fweight; } } if (ftotalweight <= 0.0) { continue; } fred /= ftotalweight; fgreen /= ftotalweight; fblue /= ftotalweight; var outOffset = iy * _outputWidth + ix; var outputPixel = res[outOffset]; outputPixel.R = (byte)(int)fred; outputPixel.G = (byte)(int)fgreen; outputPixel.B = (byte)(int)fblue; res[outOffset] = outputPixel; } } return(res); }