/// <summary> /// Reprojects a <see cref="Bitmap"/> and corresponding georeferenced metadata to /// a new coordinate system. /// </summary> /// <param name="sourceReference">The georeferenced metadata of <paramref name="sourceTile"/>.</param> /// <param name="sourceTile">The tile image.</param> /// <param name="targetReference">Output: The reprojected georeferenced metadata.</param> /// <param name="targetTile">Output: The reprojected tile image.</param> public void Reproject(WorldFile sourceReference, Bitmap sourceTile, out WorldFile targetReference, out Bitmap targetTile) { if (source == null || target == null || source.Equals(target)) { targetReference = sourceReference; targetTile = sourceTile; return; } Rectangle targetTileExtentInPixelCoordinates = GetTargetExtentInPixelCoordinates(sourceReference, sourceTile); // Get the intersection with the current viewport targetTileExtentInPixelCoordinates.Intersect(mapArgs.ImageRectangle); // Is it empty, don't return anything if (targetTileExtentInPixelCoordinates.Width == 0 || targetTileExtentInPixelCoordinates.Height == 0) { targetTile = null; targetReference = null; return; } int offsetX = targetTileExtentInPixelCoordinates.X; int offsetY = targetTileExtentInPixelCoordinates.Y; // Prepare the result tile targetTile = new Bitmap(targetTileExtentInPixelCoordinates.Size.Width, targetTileExtentInPixelCoordinates.Size.Height, PixelFormat.Format32bppArgb); using (Graphics g = Graphics.FromImage(targetTile)) { g.Clear(Color.Transparent); } ColorAccess sourceTileColorAccess = ColorAccess.Create(sourceTile); ColorAccess targetTileColorAccess = ColorAccess.Create(targetTile); // Copy values to output buffer Size sourceTileSize = sourceTile.Size; for (var i = 0; i < targetTile.Height; i++) { foreach (Tuple <Point, Point> ppair in GetValidPoints(offsetY + i, offsetY, offsetX, offsetX + targetTile.Width, sourceReference, sourceTileSize)) { Color c = sourceTileColorAccess[ppair.Item1.X, ppair.Item1.Y]; targetTileColorAccess[ppair.Item2.X, ppair.Item2.Y] = c; } } // Copy to output tile targetTileColorAccess.SetBufferToImageAtOriginalLocation(targetTile); // Compute the reference Extent outExtent = mapArgs.PixelToProj(targetTileExtentInPixelCoordinates); targetReference = new WorldFile( outExtent.Width / targetTileExtentInPixelCoordinates.Width, 0, 0, -outExtent.Height / targetTileExtentInPixelCoordinates.Height, outExtent.X, outExtent.Y); }
public void Create_BitmapNull_ThrowArgumentNullException() { // Call TestDelegate call = () => ColorAccess.Create(null); // Assert string paramName = Assert.Throws <ArgumentNullException>(call).ParamName; Assert.AreEqual("bitmap", paramName); }
public void SetBufferToImageAtOriginalLocation_BitmapNull_ThrowArgumentNullException() { // Setup ColorAccess colorAccess = ColorAccess.Create(Resources.acorn); // Call TestDelegate call = () => colorAccess.SetBufferToImageAtOriginalLocation(null); // Assert string paramName = Assert.Throws <ArgumentNullException>(call).ParamName; Assert.AreEqual("bitmap", paramName); }
public void Index_SetAtInvalidIndices_ThrowArgumentOutOfRangeException(int x, int y) { // Setup ColorAccess colorAccess = ColorAccess.Create(Resources.acorn); // Call TestDelegate call = () => colorAccess[x, y] = Color.AliceBlue; // Assert const string message = "Index must be in range x:[0,15], y:[0,15]."; TestHelper.AssertThrowsArgumentExceptionAndTestMessage <ArgumentOutOfRangeException>(call, message); }
public void Create_RectangleNotFullyWithinImage_ThrowArgumentException(int leftX, int topY, int rightX, int bottomY) { // Setup Rectangle rect = Rectangle.FromLTRB(leftX, topY, rightX, bottomY); // Call TestDelegate call = () => ColorAccess.Create(Resources.Black2x2, rect); // Assert const string message = "Toegankelijk gebied moet geheel binnen de afbeelding vallen."; string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage <ArgumentException>(call, message).ParamName; Assert.AreEqual("accessibleArea", paramName); }
public void Index_ValidIndices_ReturnColor() { // Setup ColorAccess colorAccess = ColorAccess.Create(Resources.acorn); // Call Color color1 = colorAccess[0, 0]; Color color2 = colorAccess[8, 8]; Color color3 = colorAccess[12, 6]; // Assert Color expectedColor1 = Color.FromArgb(0, 110, 55, 2); Color expectedColor2 = Color.FromArgb(255, 137, 69, 18); Color expectedColor3 = Color.FromArgb(255, 197, 171, 146); Assert.AreEqual(expectedColor1, color1); Assert.AreEqual(expectedColor2, color2); Assert.AreEqual(expectedColor3, color3); }
public void SetBufferToImageAtOriginalLocation_AfterModificationsToBuffer_TargetImageUpdated() { // Setup ColorAccess colorAccess = ColorAccess.Create(Resources.acorn); for (var i = 0; i < 16; i++) { colorAccess[i, i] = Color.Red; colorAccess[i, 15 - i] = Color.Red; } using (var targetImage = (Bitmap)Resources.acorn.Clone()) { // Call colorAccess.SetBufferToImageAtOriginalLocation(targetImage); // Assert TestHelper.AssertImagesAreEqual(Resources.acornWithCross, targetImage); } }
public void Index_SetAtValidIndices_BufferUpdated() { // Setup using (var image = (Bitmap)Resources.acorn.Clone()) { ColorAccess colorAccess = ColorAccess.Create(image); // Call colorAccess[8, 8] = Color.AliceBlue; // Assert const int expectedBufferStartIndex = 544; Assert.AreEqual(Color.AliceBlue.B, colorAccess.Buffer.ElementAt(expectedBufferStartIndex)); Assert.AreEqual(Color.AliceBlue.G, colorAccess.Buffer.ElementAt(expectedBufferStartIndex + 1)); Assert.AreEqual(Color.AliceBlue.R, colorAccess.Buffer.ElementAt(expectedBufferStartIndex + 2)); Assert.AreEqual(Color.AliceBlue.A, colorAccess.Buffer.ElementAt(expectedBufferStartIndex + 3)); // ColorAccess should not be capable of changing the source image: TestHelper.AssertImagesAreEqual(Resources.acorn, image); } }
public void Reproject(WorldFile inReference, Bitmap inTile, out WorldFile outReference, out Bitmap outTile) { // Shortcut when no projections have been assigned or they are of the same reference if (_source == null || _target == null || _source == _target) { outReference = inReference; outTile = inTile; return; } // Bounding polygon on the ground var ps = inReference.ToGroundBounds(inTile.Width, inTile.Height); // Bounding polygon on the ground in target projection var pt = ps.Shell.Reproject(_source, _target); // The target extent var ptExtent = pt.EnvelopeInternal.ToExtent(); // The target extent projected to the current viewport var ptRect = _mapArgs.ProjToPixel(ptExtent); // Get the intersection with the current viewport ptRect.Intersect(_mapArgs.ImageRectangle); // Is it empty, don't return anything if (ptRect.Width == 0 || ptRect.Height == 0) { outTile = null; outReference = null; return; } var offX = ptRect.X; var offY = ptRect.Y; // Prepare the result tile outTile = new Bitmap(ptRect.Size.Width, ptRect.Size.Height, PixelFormat.Format32bppArgb); using (var g = Graphics.FromImage(outTile)) { g.Clear(Color.Transparent); } var caIn = ColorAccess.Create(inTile); // not needed anymore var inSize = inTile.Size; inTile.Dispose(); var caOut = ColorAccess.Create(outTile); // Copy values to output buffer for (var i = 0; i < outTile.Height; i++) { foreach (Tuple <Point, Point> ppair in GetValidPoints(offY + i, offY, offX, offX + outTile.Width, inReference, inSize)) { var c = caIn[ppair.Item1.X, ppair.Item1.Y]; caOut[ppair.Item2.X, ppair.Item2.Y] = c; } } // Copy to output tile SetBitmapBuffer(outTile, caOut.Buffer); // Compute the reference var outExtent = _mapArgs.PixelToProj(ptRect); outReference = new WorldFile( outExtent.Width / ptRect.Width, 0, 0, -outExtent.Height / ptRect.Height, outExtent.X, outExtent.Y); }