/// <summary> /// Generate height map texture from height map, as a 16 bit grayscale PNG image. Grayscale is mapped from local min (black) to local highest point (white) /// Note : heightMap should be in projected coordinates (see ReprojectToCartesian()) /// </summary> /// <param name="heightMap">heightMap in projected coordinates</param> /// <param name="outputDirectory"></param> /// <returns></returns> public TextureInfo GenerateHeightMap(HeightMap heightMap, string outputDirectory, string fileName = "heightmap.png") { using (Image <Gray16> outputImage = new Image <Gray16>(heightMap.Width, heightMap.Height)) { int hMapIndex = 0; foreach (var coord in heightMap.Coordinates) { // index is i + (j * heightMap.Width); var j = hMapIndex / heightMap.Width; var i = hMapIndex - j * heightMap.Width; float gray = MathHelper.Map(heightMap.Minimum, heightMap.Maximum, 0, ushort.MaxValue, (float)(coord.Elevation ?? 0f), true); outputImage[i, j] = new Gray16((ushort)Math.Round(gray, 0)); hMapIndex++; } outputImage.Save(System.IO.Path.Combine(outputDirectory, fileName)); } TextureInfo normal = new TextureInfo(System.IO.Path.Combine(outputDirectory, fileName), TextureImageFormat.image_png, heightMap.Width, heightMap.Height); return(normal); }
/// <summary> /// Generate height map texture from height map, as a 16 bit grayscale PNG image. Grayscale is mapped from local min (black) to local highest point (white) /// Note : heightMap should be in projected coordinates (see ReprojectToCartesian()) /// </summary> /// <param name="heightMap">heightMap in projected coordinates</param> /// <param name="outputDirectory"></param> /// <returns></returns> public TextureInfo GenerateHeightMap(HeightMap heightMap, string outputDirectory, string fileName = "heightmap.png") { #if NETSTANDARD using (Image <Gray16> outputImage = new Image <Gray16>(heightMap.Width, heightMap.Height)) { // Slow way: bake coordinates to list var coords = heightMap.Coordinates.ToList(); for (int j = 0; j < heightMap.Height; j++) { for (int i = 0; i < heightMap.Width; i++) { int index = i + (j * heightMap.Width); GeoPoint point = coords[index]; Gray16 color = FromGeoPointToHeightMapColor(point, heightMap.Minimum, heightMap.Maximum); outputImage[i, j] = color; } } outputImage.Save(Path.Combine(outputDirectory, fileName)); } #elif NETFULL throw new NotImplementedException(); #endif TextureInfo normal = new TextureInfo(Path.Combine(outputDirectory, fileName), TextureImageFormat.image_png, heightMap.Width, heightMap.Height); return(normal); }
public void AreEqual() { var color1 = new Gray16(3000); var color2 = new Gray16(3000); Assert.Equal(color1, color2); }
//{ // float[] outMap = new float[(width + margin) * (height + margin)]; // using (Image<Gray16> outputImage = new Image<Gray16>(heightMap.Width, heightMap.Height)) // { // int hMapIndex = 0; // foreach (var coord in heightMap.Coordinates) // { // var j = hMapIndex / heightMap.Width; // var i = hMapIndex - j * heightMap.Width; // float gray = MathHelper.Map(heightMap.Minimum, heightMap.Maximum, 0, (float)ushort.MaxValue, (float)(coord.Elevation ?? 0f), true); // outputImage[i, j] = new Gray16((ushort)Math.Round(gray, 0)); // hMapIndex++; // } // // Resize // outputImage.Mutate(i => i.Resize(width, height)); // // Read heights from pixels again // for (int j = 0; j < height + margin; j++) // for (int i = 0; i < width + margin; i++) // { // Gray16 color = outputImage[Math.Min(i, width - 1), Math.Min(j, height - 1)]; // outMap[i + (j * width)] = FromColorToHeight(color, heightMap.Minimum, heightMap.Maximum); // } // } // return outMap; //} public float[] ResizeHeightMap_RTIN(IEnumerable <float> heightMap, int sourceWidth, int sourceHeight, int destWidth, int destHeight, float minElevation, float maxElevation, int margin) { float[] outMap = new float[(destWidth + margin) * (destHeight + margin)]; using (Image <Gray16> outputImage = new Image <Gray16>(sourceWidth, sourceHeight)) { int hMapIndex = 0; foreach (var coord in heightMap) { var j = hMapIndex / sourceWidth; var i = hMapIndex - j * sourceWidth; float gray = MathHelper.Map(minElevation, maxElevation, 0, (float)ushort.MaxValue, coord, true); outputImage[i, j] = new Gray16((ushort)Math.Round(gray, 0)); hMapIndex++; } // Resize outputImage.Mutate(i => i.Resize(destWidth, destHeight)); // Read heights from pixels again for (int j = 0; j < destHeight + margin; j++) { for (int i = 0; i < destWidth + margin; i++) { Gray16 color = outputImage[Math.Min(i, destWidth - 1), Math.Min(j, destHeight - 1)]; outMap[i + (j * destWidth)] = FromColorToHeight(color, minElevation, maxElevation); } } } return(outMap); }
static void SaveMovie(string path, RenderingOptions options, I2DMap <int>[] maps) { Console.WriteLine($"Saving movie to {path}..."); using (Image <Gray16> movie = new Image <Gray16>(options.FrameWidth, options.FrameHeight)) { for (int i = 0; i < maps.Length; i++) { var map = maps[i]; var frame = movie.Frames.CreateFrame(); for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { frame[x, y] = new Gray16((ushort)Lerp(ushort.MaxValue, 0, map[x, y] / (double)options.MaxIteration)); } } var metaData = frame.MetaData.GetFormatMetaData(GifFormat.Instance); metaData.FrameDelay = 12; } movie.Frames.RemoveFrame(0); using (var file = File.Open(path, FileMode.Create)) movie.SaveAsGif(file); } Console.WriteLine("Successfully saved!"); }
public TextureInfo GenerateHeightMap(float[] heightMap, int width, int height, float minHeight, float maxHeight, string outputDirectory, string fileName = "heightmap.png") { using (Image <Gray16> outputImage = new Image <Gray16>(width, height)) { int hMapIndex = 0; foreach (var coord in heightMap) { // index is i + (j * heightMap.Width); var j = hMapIndex / width; var i = hMapIndex - j * height; float gray = MathHelper.Map(minHeight, maxHeight, 0, ushort.MaxValue, coord, true); outputImage[i, j] = new Gray16((ushort)Math.Round(gray, 0)); hMapIndex++; } outputImage.Save(System.IO.Path.Combine(outputDirectory, fileName)); } TextureInfo normal = new TextureInfo(System.IO.Path.Combine(outputDirectory, fileName), TextureImageFormat.image_png, width, height); return(normal); }
/// <summary> /// Generate height map texture from height map, as a 16 bit grayscale PNG image. Grayscale is mapped from local min (black) to local highest point (white) /// Note : heightMap should be in projected coordinates (see ReprojectToCartesian()) /// </summary> /// <param name="heightMap">heightMap in projected coordinates</param> /// <param name="outputDirectory"></param> /// <returns></returns> public TextureInfo GenerateHeightMap(HeightMap heightMap, string outputFileName) { using (Image <Gray16> outputImage = new Image <Gray16>(heightMap.Width, heightMap.Height)) { int hMapIndex = 0; foreach (var coord in heightMap.Coordinates) { // index is i + (j * heightMap.Width); var j = hMapIndex / heightMap.Width; var i = hMapIndex - j * heightMap.Width; float gray = MathHelper.Map(heightMap.Minimum, heightMap.Maximum, 0, ushort.MaxValue, (float)(coord.Elevation ?? 0f), true); outputImage[i, j] = new Gray16((ushort)Math.Round(gray, 0)); hMapIndex++; } outputImage.Save(outputFileName, new PngEncoder() { BitDepth = PngBitDepth.Bit16 }); } TextureInfo normal = new TextureInfo(outputFileName, TextureImageFormat.image_png, heightMap.Width, heightMap.Height); return(normal); }
public void AreNotEqual() { var color1 = new Gray16(12345); var color2 = new Gray16(54321); Assert.NotEqual(color1, color2); }
public static (uint, uint, uint, uint) RGBA(this Gray16 c) { uint r = default; uint g = default; uint b = default; uint a = default; var y = uint32(c.Y); return(y, y, y, 0xffffUL); }
public void Gray16_FromVector4() { // Arrange Gray16 gray = default; const ushort expected = 32767; var vector = new Gray16(expected).ToVector4(); // Act gray.FromVector4(vector); ushort actual = gray.PackedValue; // Assert Assert.Equal(expected, actual); }
public void Gray16_FromRgba32() { // Arrange Gray16 gray = default; const byte rgb = 128; ushort scaledRgb = ImageMaths.UpscaleFrom8BitTo16Bit(rgb); ushort expected = ImageMaths.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb); // Act gray.FromRgba32(new Rgba32(rgb, rgb, rgb)); ushort actual = gray.PackedValue; // Assert Assert.Equal(expected, actual); }
public void Gray16_ToVector4(ushort input) { // Arrange var gray = new Gray16(input); // Act var actual = gray.ToVector4(); // Assert float vectorInput = input / 65535F; Assert.Equal(vectorInput, actual.X); Assert.Equal(vectorInput, actual.Y); Assert.Equal(vectorInput, actual.Z); Assert.Equal(1F, actual.W); }
public void Gray16_ToRgba32(ushort input) { // Arrange ushort expected = ImageMaths.DownScaleFrom16BitTo8Bit(input); var gray = new Gray16(input); // Act Rgba32 actual = default; gray.ToRgba32(ref actual); // Assert Assert.Equal(expected, actual.R); Assert.Equal(expected, actual.G); Assert.Equal(expected, actual.B); Assert.Equal(byte.MaxValue, actual.A); }
static void SaveFrame(string path, RenderingOptions options, I2DMap <int> map) { Console.WriteLine($"Saving frame to {path}..."); using (Image <Gray16> image = new Image <Gray16>(map.Width, map.Height)) { for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { image[x, y] = new Gray16((ushort)Lerp(ushort.MaxValue, 0, map[x, y] / (double)options.MaxIteration)); } } using (var file = File.Open(path, FileMode.Create)) image.SaveAsPng(file); } Console.WriteLine("Successfully saved!"); }
public void ToGray16Bytes(int count) { Gray8[] source = CreatePixelTestData(count); byte[] expected = new byte[count * 2]; Gray16 gray = default; for (int i = 0; i < count; i++) { int i2 = i * 2; gray.FromScaledVector4(source[i].ToScaledVector4()); OctetBytes bytes = Unsafe.As <Gray16, OctetBytes>(ref gray); expected[i2] = bytes[0]; expected[i2 + 1] = bytes[1]; } TestOperation( source, expected, (s, d) => Operations.ToGray16Bytes(this.Configuration, s, d.GetSpan(), count) ); }
public TextureInfo GenerateHeightMap(List <GeoPoint> heightMap, int width, int height, string outputFileName) { double min = double.MaxValue; double max = double.MinValue; foreach (var coord in heightMap) { min = Math.Min(min, coord.Elevation.GetValueOrDefault(0)); max = Math.Max(max, coord.Elevation.GetValueOrDefault(0)); } using (Image <Gray16> outputImage = new Image <Gray16>(width, height)) { int hMapIndex = 0; foreach (var coord in heightMap) { // index is i + (j * heightMap.Width); var j = hMapIndex / width; var i = hMapIndex - j * width; float gray = MathHelper.Map((float)min, (float)max, 0, ushort.MaxValue, (float)(coord.Elevation ?? 0f), true); outputImage[i, j] = new Gray16((ushort)Math.Round(gray, 0)); hMapIndex++; } outputImage.Save(outputFileName, new PngEncoder() { BitDepth = PngBitDepth.Bit16 }); } TextureInfo normal = new TextureInfo(outputFileName, TextureImageFormat.image_png, width, height); return(normal); }
private float FromColorToHeight(Gray16 color, float min, float max) { float height = MathHelper.Map(0, (float)ushort.MaxValue, min, max, color.PackedValue, true); return(height); }
public void FromGray16(Gray16 source) { }