/// <summary> /// Aggregates lower level image tiles to construct upper level tiles. /// </summary> /// <param name="level"> /// Zoom level. /// </param> /// <param name="tileX"> /// X coordinate. /// </param> /// <param name="tileY"> /// Y coordinate. /// </param> /// <param name="tileSerializer"> /// Serializer to invoke in order to persist the bitmap image. /// </param> public static void CreateParent(int level, int tileX, int tileY, IImageTileSerializer tileSerializer) { if (tileSerializer == null) { throw new ArgumentNullException("tileSerializer"); } int level1 = checked (level + 1); int x1 = checked (2 * tileX); int y1 = checked (2 * tileY); using (Bitmap bmp = new Bitmap(2 * Constants.TileSize, 2 * Constants.TileSize)) using (Graphics g = Graphics.FromImage(bmp)) using (Bitmap b00 = tileSerializer.Deserialize(level1, x1, y1)) using (Bitmap b10 = tileSerializer.Deserialize(level1, x1 + 1, y1)) using (Bitmap b01 = tileSerializer.Deserialize(level1, x1, y1 + 1)) using (Bitmap b11 = tileSerializer.Deserialize(level1, x1 + 1, y1 + 1)) { // Default is to display color indicating no data. g.Clear(Color.Transparent); // Draw each quadrant keeping track of number of quadrants actually drawn. short drawn = 0; if (b00 != null) { g.DrawImage(b00, 0, 0); drawn++; } if (b01 != null) { g.DrawImage(b01, 0, Constants.TileSize); drawn++; } if (b10 != null) { g.DrawImage(b10, Constants.TileSize, 0); drawn++; } if (b11 != null) { g.DrawImage(b11, Constants.TileSize, Constants.TileSize); drawn++; } // If we actually have data, shrink the tile and save it. if (drawn > 0) { using (Bitmap b = ResizeBitmap(bmp, Constants.TileSize, Constants.TileSize)) { tileSerializer.Serialize(b, level, tileX, tileY); } } } }
/// <summary> /// This function is used to generate the base level plate files. /// </summary> /// <param name="serializer"> /// Image tile serializer to retrieve the tile. /// </param> private void CreateBaseLevelPlateFiles(IImageTileSerializer serializer) { int maxPlate = (int)Math.Pow(2, this.plateFileDetails.MinOverlappedLevel); Parallel.For( 0, maxPlate, yPlate => { for (int xPlate = 0; xPlate < maxPlate; xPlate++) { // Get plate file name base don the X and Y coordinates of the plate file. string plateFilePath = System.IO.Path.Combine(this.platesFolderPath, this.plateFileDetails.MinOverlappedLevel.ToString(CultureInfo.InvariantCulture), string.Format(CultureInfo.InvariantCulture, Constants.BaseLevelPlateFormat, this.plateFileDetails.MinOverlappedLevel, xPlate, yPlate)); // Create the plate file instance. PlateFile currentPlate = new PlateFile(plateFilePath, this.plateFileDetails.LevelsPerPlate); currentPlate.Create(); for (int level = this.plateFileDetails.LevelsPerPlate - 1; level >= 0; level--) { // Get the number of tiles for the given level index. int numberOftiles = (int)Math.Pow(2, level); // Calculate the start and end index of X axis. int xStart = xPlate * numberOftiles; // Calculate the start and end index of Y axis. int yStart = yPlate * numberOftiles; // Add each tile to the plate file. for (int yIndex = 0; yIndex < numberOftiles; yIndex++) { for (int xIndex = 0; xIndex < numberOftiles; xIndex++) { TilesProcessed++; if (serializer != null) { Bitmap tile = serializer.Deserialize((this.maxLevels - (this.plateFileDetails.LevelsPerPlate - 1) + level), xStart + xIndex, yStart + yIndex); if (tile != null) { using (MemoryStream ms = new MemoryStream()) { ms.Seek(0, SeekOrigin.Begin); tile.Save(ms, format); currentPlate.AddStream(ms, level, xIndex, yIndex); } tile.Dispose(); } } } } } // Update the header and close the file stream. currentPlate.UpdateHeaderAndClose(); } }); }
/// <summary> /// This function is used to create the plate file from already generated pyramids. /// </summary> /// <param name="serializer"> /// Image tile serializer to retrieve the tile. /// </param> public void CreateFromImageTile(IImageTileSerializer serializer) { TilesProcessed = 0; PlateFile currentPlate = new PlateFile(this.PlateFilePath, this.Levels); currentPlate.Create(); for (int level = 0; level <= Levels; level++) { // Number of tiles in each direction at this level int n = (int)Math.Pow(2, level); // Add each tile to the plate file. for (int indexY = 0; indexY < n; indexY++) { for (int indexX = 0; indexX < n; indexX++) { TilesProcessed++; if (serializer != null) { Bitmap tile = serializer.Deserialize(level, indexX, indexY); if (tile != null) { using (MemoryStream ms = new MemoryStream()) { ms.Seek(0, SeekOrigin.Begin); tile.Save(ms, ImageFormat.Png); currentPlate.AddStream(ms, level, indexX, indexY); } tile.Dispose(); } } } } } // Update the header and close the file stream. currentPlate.UpdateHeaderAndClose(); }
/// <summary> /// This function is used to generate the top level plate file. /// </summary> /// <param name="serializer"> /// Image tile serializer to retrieve the tile. /// </param> private void CreateTopLevelPlateFile(IImageTileSerializer serializer) { string plateFilePath = System.IO.Path.Combine(this.platesFolderPath, Constants.TopLevelPlate); PlateFile currentPlate = new PlateFile(plateFilePath, this.maxLevels); currentPlate.Create(); for (int level = 0; level <= this.plateFileDetails.MaxOverlappedLevel; level++) { // Number of tiles in each direction at this level int n = (int)Math.Pow(2, level); // Add each tile to the plate file. for (int indexY = 0; indexY < n; indexY++) { for (int indexX = 0; indexX < n; indexX++) { TilesProcessed++; if (serializer != null) { Bitmap tile = serializer.Deserialize(level, indexX, indexY); if (tile != null) { using (MemoryStream ms = new MemoryStream()) { ms.Seek(0, SeekOrigin.Begin); tile.Save(ms, format); currentPlate.AddStream(ms, level, indexX, indexY); } tile.Dispose(); } } } } } // Update the header and close the file stream. currentPlate.UpdateHeaderAndClose(); }
public static void ToBitmap(int level, int tileX, int tileY, int[] values, IImageTileSerializer serializer, IImageTileSerializer referenceImageSerializer) { byte[] referenceImage = null; using (Bitmap image = new Bitmap(Constants.TileSize, Constants.TileSize, PixelFormat.Format32bppArgb)) { // Set the data row by row Rectangle dimension = new Rectangle(0, 0, Constants.TileSize, Constants.TileSize); BitmapData imageData = image.LockBits(dimension, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte[] rgb = new byte[imageData.Stride]; int position = -1; if (referenceImageSerializer != null) { referenceImage = TileHelper.BitmapToBytes(referenceImageSerializer.Deserialize(level, tileX, tileY)); } for (int pixelY = 0; pixelY < Constants.TileSize; pixelY++) { Array.Clear(rgb, 0, rgb.Length); int pos = 0; Color referenceColor = Color.White; for (int pixelX = 0; pixelX < Constants.TileSize; pixelX++) { Color color = Color.Transparent; position++; if (referenceImage != null) { if (referenceImage != null && referenceImage[(position * 4)] == referenceColor.B && referenceImage[(position * 4) + 1] == referenceColor.G && referenceImage[(position * 4) + 2] == referenceColor.R) { if (values != null) { color = Color.FromArgb(values[position]); } } } else { if (values != null) { color = Color.FromArgb(values[position]); } } rgb[pos++] = color.B; rgb[pos++] = color.G; rgb[pos++] = color.R; rgb[pos++] = color.A; } IntPtr p = new IntPtr(imageData.Scan0.ToInt64() + (pixelY * imageData.Stride)); System.Runtime.InteropServices.Marshal.Copy(rgb, 0, p, rgb.Length); } image.UnlockBits(imageData); if (serializer != null) { serializer.Serialize(image, level, tileX, tileY); } imageData = null; rgb = null; } }
/// <summary> /// Aggregates lower level image tiles to construct upper level tiles. /// </summary> /// <param name="level"> /// Zoom level. /// </param> /// <param name="tileX"> /// X coordinate. /// </param> /// <param name="tileY"> /// Y coordinate. /// </param> /// <param name="tileSerializer"> /// Serializer to invoke in order to persist the bitmap image. /// </param> public static void CreateParent(int level, int tileX, int tileY, IImageTileSerializer tileSerializer) { if (tileSerializer == null) { throw new ArgumentNullException("tileSerializer"); } int level1 = checked(level + 1); int x1 = checked(2 * tileX); int y1 = checked(2 * tileY); using (Bitmap bmp = new Bitmap(2 * Constants.TileSize, 2 * Constants.TileSize)) using (Graphics g = Graphics.FromImage(bmp)) using (Bitmap b00 = tileSerializer.Deserialize(level1, x1, y1)) using (Bitmap b10 = tileSerializer.Deserialize(level1, x1 + 1, y1)) using (Bitmap b01 = tileSerializer.Deserialize(level1, x1, y1 + 1)) using (Bitmap b11 = tileSerializer.Deserialize(level1, x1 + 1, y1 + 1)) { // Default is to display color indicating no data. g.Clear(Color.Transparent); // Draw each quadrant keeping track of number of quadrants actually drawn. short drawn = 0; if (b00 != null) { g.DrawImage(b00, 0, 0); drawn++; } if (b01 != null) { g.DrawImage(b01, 0, Constants.TileSize); drawn++; } if (b10 != null) { g.DrawImage(b10, Constants.TileSize, 0); drawn++; } if (b11 != null) { g.DrawImage(b11, Constants.TileSize, Constants.TileSize); drawn++; } // If we actually have data, shrink the tile and save it. if (drawn > 0) { using (Bitmap b = ResizeBitmap(bmp, Constants.TileSize, Constants.TileSize)) { tileSerializer.Serialize(b, level, tileX, tileY); } } } }