private static Image OpenImage(string path, bool cache) { if (_cachedImage.Path != null && _cachedImage.Path.Equals(path)) { return(_cachedImage); } var len = path.Length; if (len < 5) { throw new ArgumentException(@"path is too short.", @"path"); } var ext = Path.GetExtension(path); var image = ext.EndsWith(@"ppm", StringComparison.OrdinalIgnoreCase) ? PPM.Read(path) : ReadImage(path); image.Serial = _serialIndex++; if (cache) { _cachedImage = image; } return(image); }
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++; }