示例#1
0
    /// <summary>
    /// Overlays the specified layer's image with the input image.
    /// Returns true on success.
    /// </summary>
    /// <param name="layerId">the id of the layer to apply the image to</param>
    /// <param name="image">The image to apply</param>
    /// <param name="updateRegion">The region that needs to be redrawn.</param>
    /// <param name="mode">The blendmode used to apply the image.</param>
    public bool applyImageOnLayer(int layerId, Bitmap image, Rectangle updateRegion, BlendMode mode)
    {
        Layer layer = m_layers[layerId];

        // check if theres an image to apply to
        if (layer.hasFragment() == false)
        {
            return(false);
        }

        // create region relative to the image to update
        Rectangle imageRegion = layer.getLayerRegion();

        // return if there's nothing to update
        if (!updateRegion.IntersectsWith(imageRegion))
        {
            return(false);
        }

        // reduce the size of the redraw zone to only include area the layer's image covers
        Rectangle redrawRegion = Rectangle.Intersect(updateRegion, imageRegion);

        // area to redraw relative to the layer image
        // intersect to reduce area to redraw
        Point redrawLocalPosition = redrawRegion.Location;

        // offset by layer image position
        redrawLocalPosition.X -= imageRegion.X;
        redrawLocalPosition.Y -= imageRegion.Y;

        // get the layer's image
        Bitmap layerImage = layer.getImage();

        // image that will be a cropped section of drawbuffer
        Bitmap bufferCrop = new Bitmap(
            redrawRegion.Width,
            redrawRegion.Height,
            PixelFormat.Format32bppArgb);

        // copy the section of the drawbuffer that will be redarwn into the cropbuffer image
        using (Graphics m = Graphics.FromImage(bufferCrop))
        {
            m.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            m.CompositingMode    = System.Drawing.Drawing2D.CompositingMode.SourceOver;
            m.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            m.DrawImage(image,
                        new Rectangle(0, 0, redrawRegion.Width, redrawRegion.Height),
                        redrawRegion,
                        GraphicsUnit.Pixel);
        }

        //// apply the cropped image to the current layer image
        Bitmap bmp = RasterBlend.mergeImages(
            layerImage,
            bufferCrop,
            redrawLocalPosition,
            redrawRegion.Size,
            mode);

        bufferCrop.Dispose();

        // set the new image as the layer image
        layer.setImage(bmp);
        bmp.Dispose();
        return(true);
    }
示例#2
0
    /// <summary>
    /// Flattens drawbuffer to current layer and applies the changes to cached image. Runs Dispose() on cachedImage.
    /// Returns null on fail
    /// </summary>
    /// <param name="displaySize">The size of the display region in the application</param>
    /// <param name="updateRegion">The region within the final image that will be changed</param>
    /// <param name="cachedImage">The previous final image - gets Bitmap.Dispose()</param>
    /// <returns></returns>
    public Bitmap flattenImage(Size displaySize, Rectangle updateRegion, int startPos, int endPos, Bitmap cachedImage)
    {
        diagnostics.restartTimer();

        if (updateRegion.Width <= 0 || updateRegion.Height <= 0)
        {
            return(null);
        }
        if (startPos >= endPos)
        {
            return(null);
        }

        if (startPos < 0)
        {
            startPos = 0;
        }
        if (endPos > m_layerCount)
        {
            endPos = m_layerCount;
        }

        // copy previous image into the result to reduce work needed
        Bitmap result = cachedImage;

        // the image to stack layers into and apply to the reswult image after stacking
        Bitmap redrawnSection = new Bitmap(updateRegion.Width, updateRegion.Height);

        // remove all data that will be overwritten from flattening
        // this must happen before redrawnSection is written to
        using (Graphics gr = Graphics.FromImage(result))
        {
            gr.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            gr.CompositingMode    = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
            gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            gr.DrawImage(redrawnSection,
                         updateRegion,
                         new Rectangle(new Point(0, 0), redrawnSection.Size),
                         GraphicsUnit.Pixel);
        }

        diagnostics.printTimeElapsedAndRestart("PREPARE RESULT IMAGE TIME ");

        // move pixels from drawBuffer to display_canvas
        // flatten all layers
        for (int l = startPos; l < endPos; l++)
        //for (int l = m_layerCount - 1; l >= 0; l--)
        {
            // get a handle on the layer
            Layer layer = m_layers[l];
            // Console.Write("\nLayer " + l + " isVisible = " + layer.getIsVisible());

            // skip layer if is not visible or has not been set
            if (layer.getId() == int.MinValue)
            {
                continue;
            }

            if (layer.getIsVisible() == false)
            {
                continue;
            }

            if (layer.hasFragment() == false)
            {
                continue;
            }

            // create region relative to the image to update
            Rectangle imageRegion = layer.getLayerRegion();

            // get a handle on the layers image
            Bitmap layerImage = layer.getImage();

            if (layerImage == null)
            {
                continue;
            }

            // reduce the size of the redraw zone to only include area the layer's image covers
            Rectangle redrawRegion = Rectangle.Intersect(updateRegion, imageRegion);

            // area to redraw relative to the layer image
            // intersect to reduce area to redraw
            Point redrawLocalPosition = redrawRegion.Location;
            // offset by layer image position
            redrawLocalPosition.X -= imageRegion.X;
            redrawLocalPosition.Y -= imageRegion.Y;

            // go to next layer if there's nothing to update
            if (!updateRegion.IntersectsWith(imageRegion))
            {
                continue;
            }

            // create new image the size of redraw region
            Bitmap layerCrop = new Bitmap(
                redrawRegion.Width,
                redrawRegion.Height,
                PixelFormat.Format32bppArgb);

            // cut section out of layer that will be applied to the image
            using (Graphics gr = Graphics.FromImage(layerCrop))
            {
                gr.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                gr.CompositingMode    = System.Drawing.Drawing2D.CompositingMode.SourceOver;
                gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                gr.DrawImage(layerImage,
                             new Rectangle(0, 0, redrawRegion.Width, redrawRegion.Height),
                             new Rectangle(redrawLocalPosition, redrawRegion.Size),
                             GraphicsUnit.Pixel);
            }

            // apply cutout to the result image
            Bitmap stack = RasterBlend.mergeImages(
                redrawnSection,
                layerCrop,
                new Point(redrawRegion.X -= updateRegion.X, redrawRegion.Y -= updateRegion.Y),//redrawLocalPosition,
                redrawRegion.Size,
                BlendMode.Add);

            layerCrop.Dispose();

            if (redrawnSection != null)
            {
                redrawnSection.Dispose();
            }

            redrawnSection = stack;

            diagnostics.printTimeElapsedAndRestart("FLATTEN LAYER " + l + " TIME");
        } // END l

        // create final image
        Bitmap final = RasterBlend.mergeImages(
            result,
            redrawnSection,
            updateRegion.Location,
            updateRegion.Size,
            BlendMode.Add);

        // this is now the final version of Bitmap stack
        redrawnSection.Dispose();

        if (result != null)
        {
            result.Dispose();
        }

        // set new image as the result
        result = final;

        diagnostics.printTimeElapsedAndRestart("SET RESULT AND DISPOSE TIME ");
        return(result);
    }