public override ExecutionResult Run(IStepExecutionContext context) { Guard.Against.Null(Activity, nameof(Activity)); // Identify minimum horizontal offset im source images var minOffset = Activity.Registrations.Select(p => p.OffsetX).Min(); TargetImage = NewTargetImage(minOffset); _logger.LogInformation("Output image size: {width} x {height} px", TargetImage.Width, TargetImage.Height); // Composite all images. Images will have their horizontal offsets pre-calculated and overlaps // blended, so compositing just involves combining them in the correct stacking order. TargetImage.Mutate(imageContext => { // Render all images in correct stacking order foreach (var registration in Activity.Registrations.OrderByDescending(p => p.OffsetX)) { using (registration) { var projectionImage = registration.Image; // Identify horizontal offset of each image var location = new Point(registration.OffsetX - minOffset, 0); imageContext.DrawImage(projectionImage, location, PixelColorBlendingMode.Normal, 1.0f); } } }); return(ExecutionResult.Next()); }
public override ExecutionResult Run(IStepExecutionContext context) { Guard.Against.Null(TargetImage, nameof(TargetImage)); Guard.Against.Null(Activity, nameof(Activity)); // Crop if required var equirectangularOptions = _options.EquirectangularRender !; if (!equirectangularOptions.NoCrop && CropBounds != null) { _logger.LogDebug("Crop bounds: {Bounds}", CropBounds); TargetImage.Mutate(ctx => ctx.Crop(CropBounds.Value)); } return(ExecutionResult.Next()); }