Example #1
0
        /// <summary>
        /// Converts this image to an RGBA image with the palette provided.
        /// </summary>
        /// <param name="palette">The palette to convert with.</param>
        /// <returns>The RGBA image.</returns>
        public RgbaImage ToColor(Palette palette)
        {
            PaletteLayer paletteLayer = palette.Default;

            Color[] pixels = new Color[Area];
            for (int i = 0; i < Area; i++)
            {
                // TODO: Could we extend the palette by 1 and set it to be transparent to avoid branching *every* pixel?
                short index = Indices[i];
                Color color = index == TransparentIndex ? RgbaImage.Transparent : paletteLayer[index];
                pixels[i] = color;
            }

            RgbaImage image = RgbaImage.From(Width, Height, pixels).Value;

            image.Namespace = Namespace;
            image.Offset    = Offset;
            return(image);
        }
Example #2
0
        /// <summary>
        /// Takes the image given and draws it on top of the current image.
        /// Does not draw a pixel if the alpha is not fully opaque (as in
        /// alpha must be >= 1.0f).
        /// </summary>
        /// <param name="image">The image to draw on top.</param>
        /// <param name="topLeft">The top left corner to start drawing the
        /// image from.</param>
        /// <returns>True on success, false if it could not be written due to
        /// bounding issues (ex: image would write outside the bounds).
        /// </returns>
        public bool DrawOntoThis(RgbaImage image, Vec2I topLeft)
        {
            // We want to find the area we draw. This is effectively finding
            // the rectangle overlap. If there is none, we exit early.
            Vec2I drawStart = new Vec2I(Math.Max(0, topLeft.X), Math.Max(0, topLeft.Y));
            Vec2I drawEnd   = new Vec2I(Math.Min(topLeft.X + image.Width, Width), Math.Min(topLeft.Y + image.Height, Height));
            Vec2I drawRange = drawEnd - drawStart;

            if (drawRange.X <= 0 || drawRange.Y <= 0)
            {
                return(false);
            }

            // The starting coordinate from the source image is usually from
            // the top left corner, but if the offset is negative then we are
            // going to have to draw from the insides of the source image.
            Vec2I srcStart = Vec2I.Zero;

            if (topLeft.X < 0)
            {
                srcStart = srcStart.WithX(-topLeft.X);
            }
            if (topLeft.Y < 0)
            {
                srcStart = srcStart.WithY(-topLeft.Y);
            }

            // The destination coordinate is usually at the top left coordinate
            // provided, but if the top left is negative then we will start our
            // drawing at the zero index for that axis. If we have no drawing
            // overlap we'd have exited early before reaching this, so starting
            // at zero is okay.
            Vec2I destStart = topLeft;

            if (destStart.X < 0)
            {
                destStart = destStart.WithX(0);
            }
            if (destStart.Y < 0)
            {
                destStart = destStart.WithY(0);
            }

            // Now we have enough info to draw.
            RgbaImage src        = image;
            RgbaImage dest       = this;
            int       srcOffset  = (srcStart.Y * src.Width) + srcStart.X;
            int       destOffset = (destStart.Y * dest.Width) + destStart.X;

            try
            {
                for (int y = 0; y < drawRange.Y; y++)
                {
                    int srcIndex  = srcOffset;
                    int destIndex = destOffset;

                    for (int x = 0; x < drawRange.X; x++)
                    {
                        // For now, only draw the pixel if it is opaque. In the
                        // future we can do alpha blending.
                        Color srcColor = src.Pixels[srcIndex];
                        if (srcColor.a >= 1.0f)
                        {
                            dest.Pixels[destIndex] = srcColor;
                        }

                        srcIndex++;
                        destIndex++;
                    }

                    srcOffset  += src.Width;
                    destOffset += dest.Width;
                }

                return(true);
            }
            catch
            {
                return(false);
            }
        }