Example #1
0
        public static Surface CreateThumbnail(Surface sourceSurface, PdnGraphicsPath maskPath, Rectangle bounds, int thumbSideLength)
        {
            Size thumbSize = Utility.ComputeThumbnailSize(bounds.Size, thumbSideLength);

            Surface thumb = new Surface(Math.Max(5, thumbSize.Width + 4), Math.Max(5, thumbSize.Height + 4));

            thumb.Clear(ColorBgra.Transparent);
            thumb.Clear(new Rectangle(1, 1, thumb.Width - 2, thumb.Height - 2), ColorBgra.Black);

            Rectangle insetRect = new Rectangle(2, 2, thumb.Width - 4, thumb.Height - 4);

            Surface thumbInset = thumb.CreateWindow(insetRect);

            thumbInset.Clear(ColorBgra.Transparent);

            float scaleX = (float)thumbInset.Width / (float)bounds.Width;
            float scaleY = (float)thumbInset.Height / (float)bounds.Height;

            Matrix scaleMatrix = new Matrix();

            scaleMatrix.Translate(-bounds.X, -bounds.Y, System.Drawing.Drawing2D.MatrixOrder.Append);
            scaleMatrix.Scale(scaleX, scaleY, System.Drawing.Drawing2D.MatrixOrder.Append);

            thumbInset.SuperSamplingFitSurface(sourceSurface);

            Surface maskInset = new Surface(thumbInset.Size);

            maskInset.Clear(ColorBgra.Black);
            using (RenderArgs maskInsetRA = new RenderArgs(maskInset))
            {
                maskInsetRA.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                maskInsetRA.Graphics.Transform     = scaleMatrix;
                maskInsetRA.Graphics.FillPath(Brushes.White, maskPath);
                maskInsetRA.Graphics.DrawPath(Pens.White, maskPath);
            }

            scaleMatrix.Dispose();
            scaleMatrix = null;

            IntensityMaskOp maskOp = new IntensityMaskOp();

            maskOp.Apply(maskInset, thumbInset, maskInset);

            UserBlendOps.NormalBlendOp normalOp = new UserBlendOps.NormalBlendOp();
            thumbInset.ClearWithCheckboardPattern();
            normalOp.Apply(thumbInset, thumbInset, maskInset);

            maskInset.Dispose();
            maskInset = null;

            thumbInset.Dispose();
            thumbInset = null;

            using (RenderArgs thumbRA = new RenderArgs(thumb))
            {
                Utility.DrawDropShadow1px(thumbRA.Graphics, thumb.Bounds);
            }

            return(thumb);
        }
Example #2
0
        public GradientRenderer CreateGradientRenderer()
        {
            UserBlendOps.NormalBlendOp normalBlendOp = new UserBlendOps.NormalBlendOp();

            switch (this.gradientType)
            {
            case GradientType.LinearClamped:
                return(new GradientRenderers.LinearClamped(this.alphaOnly, normalBlendOp));

            case GradientType.LinearReflected:
                return(new GradientRenderers.LinearReflected(this.alphaOnly, normalBlendOp));

            case GradientType.LinearDiamond:
                return(new GradientRenderers.LinearDiamond(this.alphaOnly, normalBlendOp));

            case GradientType.Radial:
                return(new GradientRenderers.Radial(this.alphaOnly, normalBlendOp));

            case GradientType.Conical:
                return(new GradientRenderers.Conical(this.alphaOnly, normalBlendOp));

            default:
                throw new InvalidEnumArgumentException();
            }
        }
Example #3
0
        private GradientRenderer CreateGradientRenderer()
        {
            var  normalBlendOp = new UserBlendOps.NormalBlendOp();
            bool alpha_only    = SelectedGradientColorMode == GradientColorMode.Transparency;

            switch (SelectedGradientType)
            {
            case GradientType.Linear:
                return(new GradientRenderers.LinearClamped(alpha_only, normalBlendOp));

            case GradientType.LinearReflected:
                return(new GradientRenderers.LinearReflected(alpha_only, normalBlendOp));

            case GradientType.Radial:
                return(new GradientRenderers.Radial(alpha_only, normalBlendOp));

            case GradientType.Diamond:
                return(new GradientRenderers.LinearDiamond(alpha_only, normalBlendOp));

            case GradientType.Conical:
                return(new GradientRenderers.Conical(alpha_only, normalBlendOp));
            }

            throw new ArgumentOutOfRangeException("Unknown gradient type.");
        }
Example #4
0
        private SavableBitDepths GetBitDepth(Surface scratchSurface, Rectangle bounds)
        {
            bool allOpaque;
            bool all0or255Alpha;
            int  uniqueColorCount;

            Analyze(scratchSurface, bounds, out allOpaque, out all0or255Alpha, out uniqueColorCount);

            SavableBitDepths bitDepth = SavableBitDepths.Rgba32;

            if (allOpaque)
            {
                bitDepth = SavableBitDepths.Rgb24;

                if (uniqueColorCount <= 256)
                {
                    bitDepth = SavableBitDepths.Rgb8;
                }
            }
            else if (all0or255Alpha && uniqueColorCount < 256)
            {
                bitDepth = SavableBitDepths.Rgba8;
            }

            // if bit depth is 24 or 8, then we have to do away with the alpha channel
            // for 8-bit, we must have pixels that have either 0 or 255 alpha
            if (bitDepth == SavableBitDepths.Rgb8 ||
                bitDepth == SavableBitDepths.Rgba8 ||
                bitDepth == SavableBitDepths.Rgb24)
            {
                UserBlendOps.NormalBlendOp blendOp = new UserBlendOps.NormalBlendOp();

                unsafe
                {
                    for (int y = bounds.Top; y < bounds.Bottom; ++y)
                    {
                        ColorBgra *srcPtr = scratchSurface.GetPointAddressUnchecked(bounds.Left, y);
                        ColorBgra *endPtr = srcPtr + bounds.Width;

                        while (srcPtr < endPtr)
                        {
                            if (srcPtr->A < 128 && bitDepth == SavableBitDepths.Rgba8)
                            {
                                *srcPtr = ColorBgra.FromBgra(0, 0, 0, 0);
                            }
                            else
                            {
                                *srcPtr = blendOp.Apply(ColorBgra.White, *srcPtr);
                            }

                            srcPtr++;
                        }
                    }
                }
            }


            return(bitDepth);
        }
Example #5
0
        private GradientRenderer CreateGradientRenderer()
        {
            var op = new UserBlendOps.NormalBlendOp();

            return(SelectedGradientType switch {
                GradientType.Linear => new GradientRenderers.LinearClamped(false, op),
                GradientType.LinearReflected => new GradientRenderers.LinearReflected(false, op),
                GradientType.Radial => new GradientRenderers.Radial(false, op),
                GradientType.Diamond => new GradientRenderers.LinearDiamond(false, op),
                GradientType.Conical => new GradientRenderers.Conical(false, op),
                _ => throw new ArgumentOutOfRangeException("Unknown gradient type."),
            });
Example #6
0
        public override Surface RenderThumbnail(int maxEdgeLength)
        {
            Size    thumbSize = Utility.ComputeThumbnailSize(this.Size, maxEdgeLength);
            Surface thumb     = new Surface(thumbSize);

            thumb.SuperSamplingFitSurface(this.surface);

            Surface thumb2 = new Surface(thumbSize);

            thumb2.ClearWithCheckboardPattern();
            UserBlendOps.NormalBlendOp nbop = new UserBlendOps.NormalBlendOp();
            nbop.Apply(thumb2, thumb);

            thumb.Dispose();
            thumb = null;

            return(thumb2);
        }
        protected override void InitDialogFromToken(EffectConfigToken effectToken)
        {
            base.InitDialogFromToken(effectToken);

            UserBlendOp setOp = ((CloudsEffectConfigToken)effectToken).BlendOp;

            if (setOp == null)
            {
                setOp = new UserBlendOps.NormalBlendOp();
            }

            foreach (object op in this.comboBlendModes.Items)
            {
                if (0 == string.Compare(op.ToString(), setOp.ToString(), StringComparison.CurrentCultureIgnoreCase))
                {
                    this.comboBlendModes.SelectedItem = op;
                    break;
                }
            }
        }
Example #8
0
        private unsafe Bitmap reduceToPalette(Surface surface, byte ditheringLevel, byte threshold, ProgressEventHandler progressCallback)
        {
            BinaryPixelOp blendOp = new UserBlendOps.NormalBlendOp();

            for (int y = 0; y < surface.Height; y++)
            {
                ColorBgra *ptr = surface.GetRowAddressUnchecked(y);

                for (int x = 0; x < surface.Width; x++)
                {
                    if (ptr->A < threshold)
                    {
                        ptr->Bgra = 0x00000000;
                    }
                    else
                    {
                        ptr->Bgra = blendOp.Apply(ColorBgra.White, *ptr).Bgra;
                    }
                    ptr++;
                }
            }

            int ColorCount = 256;

            //Search for transparent pixel and add it (do this because if there is no transparent pixel, quantize with -1 color)
            for (int x = 0; x < surface.Width; x++)
            {
                for (int y = 0; y < surface.Height; y++)
                {
                    Color color = surface.GetPoint(x, y);
                    if (color.A == 0)
                    {
                        goto TransparentColorFound;
                    }
                }
            }
            ColorCount = 255;
TransparentColorFound:

            return(Quantize(surface, ditheringLevel, ColorCount, true, progressCallback));
        }
Example #9
0
        public static Surface CreateThumbnail(Surface sourceSurface, PdnGraphicsPath maskPath, Rectangle bounds, int thumbSideLength)
        {
            Size thumbSize = Utility.ComputeThumbnailSize(bounds.Size, thumbSideLength);

            Surface thumb = new Surface(Math.Max(5, thumbSize.Width + 4), Math.Max(5, thumbSize.Height + 4));
            thumb.Clear(ColorBgra.Transparent);
            thumb.Clear(new Rectangle(1, 1, thumb.Width - 2, thumb.Height - 2), ColorBgra.Black);

            Rectangle insetRect = new Rectangle(2, 2, thumb.Width - 4, thumb.Height - 4);

            Surface thumbInset = thumb.CreateWindow(insetRect);
            thumbInset.Clear(ColorBgra.Transparent);

            float scaleX = (float)thumbInset.Width / (float)bounds.Width;
            float scaleY = (float)thumbInset.Height / (float)bounds.Height;

            Matrix scaleMatrix = new Matrix();
            scaleMatrix.Translate(-bounds.X, -bounds.Y, System.Drawing.Drawing2D.MatrixOrder.Append);
            scaleMatrix.Scale(scaleX, scaleY, System.Drawing.Drawing2D.MatrixOrder.Append);

            thumbInset.SuperSamplingFitSurface(sourceSurface);

            Surface maskInset = new Surface(thumbInset.Size);
            maskInset.Clear(ColorBgra.Black);
            using (RenderArgs maskInsetRA = new RenderArgs(maskInset))
            {
                maskInsetRA.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                maskInsetRA.Graphics.Transform = scaleMatrix;
                maskInsetRA.Graphics.FillPath(Brushes.White, maskPath);
                maskInsetRA.Graphics.DrawPath(Pens.White, maskPath);
            }

            scaleMatrix.Dispose();
            scaleMatrix = null;

            IntensityMaskOp maskOp = new IntensityMaskOp();
            maskOp.Apply(maskInset, thumbInset, maskInset);

            UserBlendOps.NormalBlendOp normalOp = new UserBlendOps.NormalBlendOp();
            thumbInset.ClearWithCheckboardPattern();
            normalOp.Apply(thumbInset, thumbInset, maskInset);

            maskInset.Dispose();
            maskInset = null;

            thumbInset.Dispose();
            thumbInset = null;

            using (RenderArgs thumbRA = new RenderArgs(thumb))
            {
                Utility.DrawDropShadow1px(thumbRA.Graphics, thumb.Bounds);
            }

            return thumb;
        }
Example #10
0
        protected unsafe override sealed void OnSaveT(
            Document input,
            Stream output,
            PropertyBasedSaveConfigToken token,
            Surface scratchSurface,
            ProgressEventHandler progressCallback)
        {
            // flatten the document -- render w/ transparent background
            scratchSurface.Clear(ColorBgra.Transparent);

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, false);
            }

            // load properties from token
            int thresholdFromToken = GetThresholdFromToken(token);
            int ditherLevel        = GetDitherLevelFromToken(token);

            Set <SavableBitDepths> allowedBitDepths = CreateAllowedBitDepthListFromToken(token);

            if (allowedBitDepths.Count == 0)
            {
                throw new ArgumentException("there must be at least 1 element returned from CreateAllowedBitDepthListFromToken()");
            }

            // allowedBitDepths.Count >= 1

            // set to 1 unless allowedBitDepths contains only Rgb8 and Rgba8
            int threshold;

            if (allowedBitDepths.IsSubsetOf(Set.Create(SavableBitDepths.Rgb8, SavableBitDepths.Rgba8)))
            {
                threshold = thresholdFromToken;
            }
            else
            {
                threshold = 1;
            }

            // Analyze image, try to detect what bit-depth or whatever to use, based on allowedBitDepths
            bool allOpaque;
            bool all0or255Alpha;
            int  uniqueColorCount;

            Analyze(scratchSurface, out allOpaque, out all0or255Alpha, out uniqueColorCount);

            Set <SavableBitDepths> losslessBitDepths = new Set <SavableBitDepths>();

            losslessBitDepths.Add(SavableBitDepths.Rgba32);

            if (allOpaque)
            {
                losslessBitDepths.Add(SavableBitDepths.Rgb24);

                if (uniqueColorCount <= 256)
                {
                    losslessBitDepths.Add(SavableBitDepths.Rgb8);
                }
            }
            else if (all0or255Alpha && uniqueColorCount < 256)
            {
                losslessBitDepths.Add(SavableBitDepths.Rgba8);
            }

            SavableBitDepths bitDepth = ChooseBitDepth(allowedBitDepths, losslessBitDepths, allOpaque, all0or255Alpha, uniqueColorCount);

            if (bitDepth == SavableBitDepths.Rgba8 && threshold == 0 && allowedBitDepths.Contains(SavableBitDepths.Rgba8) && allowedBitDepths.Contains(SavableBitDepths.Rgb8))
            {
                // threshold of 0 should effectively force full 256 color palette, instead of 255+1 transparent
                bitDepth = SavableBitDepths.Rgb8;
            }

            // if bit depth is 24 or 8, then we have to do away with the alpha channel
            // for 8-bit, we must have pixels that have either 0 or 255 alpha
            if (bitDepth == SavableBitDepths.Rgb8 ||
                bitDepth == SavableBitDepths.Rgba8 ||
                bitDepth == SavableBitDepths.Rgb24)
            {
                UserBlendOps.NormalBlendOp blendOp = new UserBlendOps.NormalBlendOp();

                for (int y = 0; y < scratchSurface.Height; ++y)
                {
                    for (int x = 0; x < scratchSurface.Width; ++x)
                    {
                        ColorBgra p = scratchSurface[x, y];

                        if (p.A < threshold && bitDepth == SavableBitDepths.Rgba8)
                        {
                            p = ColorBgra.FromBgra(0, 0, 0, 0);
                        }
                        else
                        {
                            p = blendOp.Apply(ColorBgra.White, p);
                        }

                        scratchSurface[x, y] = p;
                    }
                }
            }

            Tracing.Ping("Chose " + bitDepth + ", ditherLevel=" + ditherLevel + ", threshold=" + threshold);

            // finally, do the save.
            FinalSave(input, output, scratchSurface, ditherLevel, bitDepth, token, progressCallback);
        }