/// <summary> /// Draws the <see cref="ImageStack"/> to the specified rectangle.</summary> /// <param name="context"> /// The <see cref="DrawingContext"/> for the drawing.</param> /// <param name="target"> /// The drawing region within <paramref name="context"/>, in device-independent pixels. /// </param> /// <returns> /// <c>true</c> if all <see cref="ImageStack"/> elements were drawn without errors; /// otherwise, <c>false</c>.</returns> /// <remarks> /// <b>DrawImageStack</b> draws the selected <see cref="Frames"/> of all <see /// cref="ImageStack"/> elements to the specified <paramref name="target"/> rectangle within /// the specified <paramref name="context"/>.</remarks> private bool DrawImageStack(DrawingContext context, Rect target) { Debug.Assert(ImageStack.Count == Frames.Count); // fail if no images are available if (ImageStack.Count == 0) { return(false); } // draw selected frames of all images for (int i = 0; i < ImageStack.Count; i++) { ImageStackEntry entry = ImageStack[i]; // quit on first unavailable image EntityImage image = entry.Image.Value; if (image == null) { return(false); } // determine selected frame int frameIndex = Frames[i] % image.Frames.Count; ImageFrame frame = image.Frames[frameIndex]; // quit on first unavailable bitmap if (frame.Source.Value == null) { return(false); } // get desired image scaling, unless disabled ImageScaling scalingX = ImageScaling.None, scalingY = ImageScaling.None; if (!entry.UseUnscaled) { scalingX = image.ScalingX; scalingY = image.ScalingY; } // draw frame with specified display parameters if (!ImageUtility.DrawOutlineFrame(context, Brushes.Black, target, frame.Source.Value.Bitmap, frame.Bounds, Polygon, scalingX, scalingY, entry.ColorShift, entry.Offset, entry.ScalingVector)) { return(false); } } return(true); }
/// <summary> /// Initializes a new instance of the <see cref="ChangeFrame"/> class with the specified /// <see cref="ImageStackEntry"/>.</summary> /// <param name="entry"> /// The <see cref="ImageStackEntry"/> whose <see cref="ImageStackEntry.SingleFrame"/> value /// to change.</param> /// <exception cref="ArgumentException"> /// <paramref name="entry"/> contains an <see cref="ImageStackEntry.Image"/> that is a null /// reference or contains less than two <see cref="EntityImage.Frames"/>.</exception> /// <exception cref="ArgumentNullException"> /// <paramref name="entry"/> is a null reference.</exception> /// <remarks> /// The data of the specified <paramref name="entry"/> may be changed in the dialog, as /// indicated by the value of the <see cref="DataChanged"/> property.</remarks> public ChangeFrame(ImageStackEntry entry) { if (entry == null) { ThrowHelper.ThrowArgumentNullException("entry"); } EntityImage image = entry.Image.Value; if (image == null) { ThrowHelper.ThrowArgumentExceptionWithFormat("entry", Tektosyne.Strings.ArgumentSpecifiesInvalid, "Image"); } if (image.Frames.Count < 2) { ThrowHelper.ThrowArgumentExceptionWithFormat("entry", Global.Strings.ArgumentSpecifiesSingleFrame, "Image"); } this._entry = entry; InitializeComponent(); Title += image.Id; // prepare list box for image frames FrameList.Polygon = MasterSection.Instance.Areas.MapGrid.Element; // use image scaling unless disabled if (!entry.UseUnscaled) { FrameList.ScalingX = image.ScalingX; FrameList.ScalingY = image.ScalingY; } // add image frames to list box Debug.Assert(image.Frames.Count >= 2); foreach (ImageFrame frame in image.Frames) { FrameList.Items.Add(new ImageListBoxItem(frame)); } // select initial item in Frames list box int index = Math.Max(0, this._entry.SingleFrame); FrameList.SelectAndShow(Math.Min(index, FrameList.Items.Count - 1)); }
/// <summary> /// Copies the specified <see cref="ImageFrame"/> to the specified catalog tile.</summary> /// <param name="index"> /// The catalog tile index where to copy the specified <paramref name="frame"/>.</param> /// <param name="entry"> /// The <see cref="ImageStackEntry"/> whose <see cref="ImageStackEntry.Image"/> contains the /// specified <paramref name="frame"/>.</param> /// <param name="frame"> /// The <see cref="ImageFrame"/> specifying the <see cref="ImageFrame.Source"/> bitmap and /// the <see cref="ImageFrame.Bounds"/> to copy.</param> /// <returns> /// <c>true</c> if copying succeeded; otherwise, <c>false</c>.</returns> private bool CopyImageFrame(int index, ImageStackEntry entry, ImageFrame frame) { // retrieve image file bitmap WriteableBitmap bitmap = frame.Source.Value.Bitmap; if (bitmap == null) { return(false); } // check for invalid frame bounds RectI source = frame.Bounds; if (source.X < 0 || source.Y < 0 || source.Width < 1 || source.Height < 1 || source.X + source.Width > bitmap.Width || source.Y + source.Height > bitmap.Height) { return(false); } // get desired image scaling, unless disabled ImageScaling scalingX = ImageScaling.None, scalingY = ImageScaling.None; if (!entry.UseUnscaled) { scalingX = entry.Image.Value.ScalingX; scalingY = entry.Image.Value.ScalingY; } // determine bounds of catalog tile RectI target = GetTileBounds(index); RectI tileBounds = new RectI(0, 0, target.Width, target.Height); // draw frame with specified display parameters TileCopyBuffer.Clear(); ImageUtility.DrawFrame(TileCopyBuffer, null, tileBounds, bitmap, source, scalingX, scalingY, entry.ColorShift, entry.Offset, entry.ScalingVector); // perform alpha blending with catalog bitmap Catalog.Overlay(target.X, target.Y, TileCopyBuffer, tileBounds); return(true); }