private Image <Rgba32> Reproject(Registration registration) { var definition = registration.Definition; // Preserve 2:1 equirectangular aspect ratio var maxWidth = _options.ImageSize * 2; var maxHeight = _options.ImageSize; // Determine pixel ranges of projected image so we can limit our processing to longitudes visible to satellite // Unwrap the longitude range to simplify maths var longitudeRange = new Range( definition.LongitudeRange.Start, definition.LongitudeRange.End).UnwrapLongitude(); var latitudeRange = new Range(definition.LatitudeRange.Start, definition.LatitudeRange.End); _logger.LogInformation("{definition:l0} latitude range {startRange:F2} to {endRange:F2} degrees", definition.DisplayName, Angle.FromRadians(latitudeRange.Start).Degrees, Angle.FromRadians(latitudeRange.End).Degrees); _logger.LogInformation("{definition:l0} unwrapped longitude range {startRange:F2} to {endRange:F2} degrees", definition.DisplayName, Angle.FromRadians(longitudeRange.Start).Degrees, Angle.FromRadians(longitudeRange.End).Degrees); // Get size of projection in pixels var xRange = new PixelRange(longitudeRange, a => a.ScaleToWidth(maxWidth)); // Restrict height of image to the visible range if we are not performing explicit cropping or no cropping var yRange = _options.EquirectangularRender?.NoCrop == true || _options.EquirectangularRender?.ExplicitCrop == true ? new PixelRange(0, maxHeight) : new PixelRange(latitudeRange, a => a.ScaleToHeight(maxHeight)); _logger.LogInformation("{definition:l0} pixel range X: {minX} - {maxX} px", definition.DisplayName, xRange.Start, xRange.End); _logger.LogInformation("{definition:l0} pixel range Y: {minY} - {maxY} px", definition.DisplayName, yRange.Start, yRange.End); _logger.LogInformation("{definition:l0} width: {targetWidth} px", definition.DisplayName, xRange.Range); _logger.LogInformation("{definition:l0} height: {targetWidth} px", definition.DisplayName, yRange.Range); // Create target image with the correct dimensions for the projected satellite image var target = new Image <Rgba32>(xRange.Range, yRange.Range); _logger.LogInformation("{definition:l0} Reprojecting", definition.DisplayName); // Perform reprojection var operation = new ReprojectRowOperation(registration, SourceImage !, target, xRange.Start, yRange.Start, _options); ParallelRowIterator.IterateRows(Configuration.Default, target.Bounds(), in operation); return(target); }
private static PixelRange[] ReadAwakeTextColors(string rgbColor) { PixelRange[] pixelRange = new PixelRange[3]; int pixelIndex = 0; int index; int lastIndex = 0; do { index = rgbColor.IndexOf(',', lastIndex); string pixelColorValue = rgbColor.Substring(lastIndex, index != -1 ? (index - lastIndex) : rgbColor.Length - lastIndex); if (pixelColorValue.Contains("-")) { pixelColorValue = pixelColorValue.StripAllSpaces(); var minMaxValues = pixelColorValue.Split('-'); if (minMaxValues.Length != 2) { throw new Exception("The AwakeTextPixelColorRgb needs to have a value on both side of the - symbol. Such as 50-120"); } PixelRange range = new PixelRange() { PixelColorMin = Convert.ToInt32(minMaxValues[0]), PixelColorMax = Convert.ToInt32(minMaxValues[1]), }; if (range.PixelColorMin >= 0 && range.PixelColorMin <= 255 && range.PixelColorMax >= 0 && range.PixelColorMax <= 255) { pixelRange[pixelIndex] = range; } else { throw new Exception("Pixel color need to be within 0 and 255"); } } else { pixelColorValue = pixelColorValue.StripAllExceptNumbers(); byte pixelColorValueInt = Convert.ToByte(pixelColorValue); PixelRange range = new PixelRange() { PixelColorMin = pixelColorValueInt, PixelColorMax = pixelColorValueInt, }; if (range.PixelColorMin >= 0 && range.PixelColorMin <= 255 && range.PixelColorMax >= 0 && range.PixelColorMax <= 255) { pixelRange[pixelIndex] = range; } else if (range.PixelColorMax >= 0 && range.PixelColorMax <= 255) { throw new Exception("Pixel color need to be within 0 and 255"); } } lastIndex = index + 1; pixelIndex++; } while (index != -1); return(pixelRange); }