示例#1
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
        {
            float radians = (float)ImageMaths.DegreesToRadians(this.Angle);
            double cosradians = Math.Cos(radians);
            double sinradians = Math.Sin(radians);

            float lumR = .213f;
            float lumG = .715f;
            float lumB = .072f;

            float oneMinusLumR = 1 - lumR;
            float oneMinusLumG = 1 - lumG;
            float oneMinusLumB = 1 - lumB;

            // The matrix is set up to preserve the luminance of the image.
            // See http://graficaobscura.com/matrix/index.html
            // Number are taken from https://msdn.microsoft.com/en-us/library/jj192162(v=vs.85).aspx
            Matrix4x4 matrix4X4 = new Matrix4x4()
            {
                M11 = (float)(lumR + (cosradians * oneMinusLumR) - (sinradians * lumR)),
                M12 = (float)(lumR - (cosradians * lumR) - (sinradians * 0.143)),
                M13 = (float)(lumR - (cosradians * lumR) - (sinradians * oneMinusLumR)),
                M21 = (float)(lumG - (cosradians * lumG) - (sinradians * lumG)),
                M22 = (float)(lumG + (cosradians * oneMinusLumG) + (sinradians * 0.140)),
                M23 = (float)(lumG - (cosradians * lumG) + (sinradians * lumG)),
                M31 = (float)(lumB - (cosradians * lumB) + (sinradians * oneMinusLumB)),
                M32 = (float)(lumB - (cosradians * lumB) - (sinradians * 0.283)),
                M33 = (float)(lumB + (cosradians * oneMinusLumB) + (sinradians * lumB))
            };

            this.matrix = matrix4X4;
        }
 /// <inheritdoc/>
 protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
 {
     if (this.Greyscale)
     {
         new GreyscaleBt709().Apply(source, source, sourceRectangle);
     }
 }
示例#3
0
        /// <inheritdoc/>
        protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            int sourceY = sourceRectangle.Y;
            int sourceBottom = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX = sourceRectangle.Right;
            Vector3 inverseVector = Vector3.One;

            Parallel.For(
                startY,
                endY,
                y =>
                    {
                        if (y >= sourceY && y < sourceBottom)
                        {
                            for (int x = startX; x < endX; x++)
                            {
                                Color color = source[x, y];
                                Vector3 vector = inverseVector - color.ToVector3();
                                target[x, y] = new Color(vector, color.A);
                            }
                            this.OnRowProcessed();
                        }
                    });
        }
        /// <inheritdoc/>
        protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            if (source.Bounds == target.Bounds)
            {
                target.SetPixels(target.Width, target.Height, source.Pixels);
                return;
            }

            int targetY = this.cropRectangle.Y;
            int startX = targetRectangle.X;
            int targetX = this.cropRectangle.X;
            int endX = this.cropRectangle.Width;
            int maxX = endX - 1;
            int maxY = this.cropRectangle.Bottom - 1;

            Parallel.For(
            startY,
            endY,
            y =>
            {
                for (int x = startX; x < endX; x++)
                {
                    int offsetY = y + targetY;
                    offsetY = offsetY.Clamp(0, maxY);

                    int offsetX = x + targetX;
                    offsetX = offsetX.Clamp(0, maxX);

                    target[x, y] = source[offsetX, offsetY];
                }
                this.OnRowProcessed();
            });
        }
        /// <inheritdoc/>
        public void Encode(ImageBase image, Stream stream)
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            int imageWidth = image.Width;
            int imageHeight = image.Height;
            ushort max = JpegConstants.MaxLength;

            if (imageWidth > max || imageHeight > max)
            {
                throw new ImageFormatException($"Image dimensions exceed maximum allowable bounds of {max}px.");
            }

            using (EndianBinaryWriter writer = new EndianBinaryWriter(new BigEndianBitConverter(), stream))
            {
                this.WriteApplicationHeader(image, writer);
                this.WriteDescreteQuantizationTables(writer);
                this.WriteStartOfFrame(image, writer);
                this.WriteHuffmanTables(writer);
                this.WriteStartOfScan(image, writer);

                writer.Write(new[] { JpegConstants.Markers.XFF, JpegConstants.Markers.EOI });
            }
        }
示例#6
0
 /// <inheritdoc/>
 protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
 {
     float contrast = (100f + this.Value) / 100f;
     int sourceY = sourceRectangle.Y;
     int sourceBottom = sourceRectangle.Bottom;
     int startX = sourceRectangle.X;
     int endX = sourceRectangle.Right;
     Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1);
     Vector4 shiftVector = new Vector4(.5f, .5f, .5f, 1);
     Parallel.For(
         startY,
         endY,
         y =>
             {
                 if (y >= sourceY && y < sourceBottom)
                 {
                     for (int x = startX; x < endX; x++)
                     {
                         Vector4 color = Color.Expand(source[x, y]).ToVector4();
                         color -= shiftVector;
                         color *= contrastVector;
                         color += shiftVector;
                         target[x, y] = Color.Compress(new Color(color));
                     }
                     this.OnRowProcessed();
                 }
             });
 }
示例#7
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
        {
            float saturationFactor = this.saturation / 100f;

            // Stop at -1 to prevent inversion.
            saturationFactor++;

            // The matrix is set up to "shear" the colour space using the following set of values.
            // Note that each colour component has an effective luminance which contributes to the
            // overall brightness of the pixel.
            // See http://graficaobscura.com/matrix/index.html
            float saturationComplement = 1.0f - saturationFactor;
            float saturationComplementR = 0.3086f * saturationComplement;
            float saturationComplementG = 0.6094f * saturationComplement;
            float saturationComplementB = 0.0820f * saturationComplement;

            Matrix4x4 matrix4X4 = new Matrix4x4()
            {
                M11 = saturationComplementR + saturationFactor,
                M12 = saturationComplementR,
                M13 = saturationComplementR,
                M21 = saturationComplementG,
                M22 = saturationComplementG + saturationFactor,
                M23 = saturationComplementG,
                M31 = saturationComplementB,
                M32 = saturationComplementB,
                M33 = saturationComplementB + saturationFactor,
            };

            this.matrix = matrix4X4;
        }
示例#8
0
        /// <inheritdoc/>
        protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            float threshold = this.Value;
            Color upper = this.UpperColor;
            Color lower = this.LowerColor;
            int sourceY = sourceRectangle.Y;
            int sourceBottom = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX = sourceRectangle.Right;

            Parallel.For(
                startY,
                endY,
                y =>
                    {
                        if (y >= sourceY && y < sourceBottom)
                        {
                            for (int x = startX; x < endX; x++)
                            {
                                Color color = source[x, y];

                                // Any channel will do since it's greyscale.
                                target[x, y] = color.B >= threshold ? upper : lower;
                            }
                            this.OnRowProcessed();
                        }
                    });
        }
        /// <inheritdoc/>
        public void Encode(ImageBase image, Stream stream)
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            int imageWidth = image.Width;
            int imageHeight = image.Height;

            SampleRow[] rows = new SampleRow[imageHeight];

            Parallel.For(
                0,
                imageHeight,
                y =>
                    {
                        byte[] samples = new byte[imageWidth * 3];

                        for (int x = 0; x < imageWidth; x++)
                        {
                            Bgra32 color = Color.ToNonPremultiplied(image[x, y]);

                            int start = x * 3;
                            samples[start] = color.R;
                            samples[start + 1] = color.G;
                            samples[start + 2] = color.B;
                        }

                        rows[y] = new SampleRow(samples, imageWidth, 8, 3);
                    });

            using (JpegImage jpg = new JpegImage(rows, Colorspace.RGB))
            {
                jpg.WriteJpeg(stream, new CompressionParameters { Quality = this.Quality });
            }
        }
示例#10
0
        /// <inheritdoc/>
        protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            float brightness = this.Value / 100f;
            int sourceY = sourceRectangle.Y;
            int sourceBottom = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX = sourceRectangle.Right;

            Parallel.For(
                startY,
                endY,
                y =>
                    {
                        if (y >= sourceY && y < sourceBottom)
                        {
                            for (int x = startX; x < endX; x++)
                            {
                                Color color = Color.Expand(source[x, y]);

                                Vector3 vector3 = color.ToVector3();
                                vector3 += new Vector3(brightness);

                                target[x, y] = Color.Compress(new Color(vector3, color.A));
                            }
                            this.OnRowProcessed();
                        }
                    });
        }
示例#11
0
        /// <inheritdoc/>
        protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            float alpha = this.Value / 100f;
            int sourceY = sourceRectangle.Y;
            int sourceBottom = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX = sourceRectangle.Right;
            Vector4 alphaVector = new Vector4(1, 1, 1, alpha);

            Parallel.For(
                startY,
                endY,
                y =>
                    {
                        if (y >= sourceY && y < sourceBottom)
                        {
                            for (int x = startX; x < endX; x++)
                            {
                                Vector4 color = Color.ToNonPremultiplied(source[x, y]).ToVector4();
                                color *= alphaVector;
                                target[x, y] = Color.FromNonPremultiplied(new Color(color));
                            }
                            this.OnRowProcessed();
                        }
                    });
        }
示例#12
0
 public override QuantizedImage Quantize(ImageBase image, int maxColors)
 {
     colors = NumUtils.Clamp(maxColors, 1, 255);
     if (octree == null){
         octree = new Octree(GetBitsNeededForColorDepth(maxColors));
     }
     return base.Quantize(image, maxColors);
 }
示例#13
0
 public void Encode(ImageBase image, Stream stream)
 {
     JpegEncoderCore encode = new JpegEncoderCore();
     if (subsampleSet){
         encode.Encode(image, stream, Quality, Subsample);
     } else{
         encode.Encode(image, stream, Quality, Quality >= 80 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420);
     }
 }
        /// <summary>
        /// Applies the process to the specified portion of the specified <see cref="ImageBase"/> at the specified location
        /// and with the specified size.
        /// </summary>
        /// <param name="target">Target image to apply the process to.</param>
        /// <param name="source">The source image. Cannot be null.</param>
        /// <param name="sourceRectangle">
        /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
        /// </param>
        /// <param name="startY">The index of the row within the source image to start processing.</param>
        /// <param name="endY">The index of the row within the source image to end processing.</param>
        /// <param name="kernel">The kernel operator.</param>
        private void ApplyConvolution(
            ImageBase target,
            ImageBase source,
            Rectangle sourceRectangle,
            int startY,
            int endY,
            float[,] kernel)
        {
            int kernelHeight = kernel.GetLength(0);
            int kernelWidth = kernel.GetLength(1);
            int radiusY = kernelHeight >> 1;
            int radiusX = kernelWidth >> 1;

            int sourceY = sourceRectangle.Y;
            int sourceBottom = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX = sourceRectangle.Right;
            int maxY = sourceBottom - 1;
            int maxX = endX - 1;

            Parallel.For(
                startY,
                endY,
                y =>
                {
                    if (y >= sourceY && y < sourceBottom)
                    {
                        for (int x = startX; x < endX; x++)
                        {
                            Color destination = new Color();

                            // Apply each matrix multiplier to the color components for each pixel.
                            for (int fy = 0; fy < kernelHeight; fy++)
                            {
                                int fyr = fy - radiusY;
                                int offsetY = y + fyr;

                                offsetY = offsetY.Clamp(0, maxY);

                                for (int fx = 0; fx < kernelWidth; fx++)
                                {
                                    int fxr = fx - radiusX;
                                    int offsetX = x + fxr;

                                    offsetX = offsetX.Clamp(0, maxX);

                                    Color currentColor = source[offsetX, offsetY];
                                    destination += kernel[fy, fx] * currentColor;
                                }
                            }

                            target[x, y] = destination;
                        }
                        this.OnRowProcessed();
                    }
                });
        }
示例#15
0
 /// <inheritdoc/>
 protected override void AfterApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
 {
     new Vignette { Color = new Color(102 / 255f, 34 / 255f, 0) }.Apply(target, target, targetRectangle);
     new Glow
     {
         Color = new Color(1, 153 / 255f, 102 / 255f, .7f),
         RadiusX = target.Width / 4f,
         RadiusY = target.Width / 4f
     }
     .Apply(target, target, targetRectangle);
 }
示例#16
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
        {
            if (this.kernelY == null)
            {
                this.kernelY = this.CreateBoxKernel(false);
            }

            if (this.kernelX == null)
            {
                this.kernelX = this.CreateBoxKernel(true);
            }
        }
示例#17
0
        public OAMEditor(XElement langxml, Bank bank, SpriteBase sprite, ImageBase image, PaletteBase palette)
        {
            InitializeComponent();
            this.bank = bank;
            numOAM.Maximum = bank.oams.Length - 1;

            preview = true;
            this.sprite = sprite;
            this.image = image;
            this.palette = palette;

            Read_Language(langxml);
        }
示例#18
0
 /// <summary>
 /// Execute the first pass through the pixels in the image
 /// </summary>
 /// <param name="source">The source data</param>
 /// <param name="width">The width in pixels of the image.</param>
 /// <param name="height">The height in pixels of the image.</param>
 protected virtual void FirstPass(ImageBase source, int width, int height)
 {
     // Loop through each row
     for (int y = 0; y < height; y++)
     {
         // And loop through each column
         for (int x = 0; x < width; x++)
         {
             // Now I have the pixel, call the FirstPassQuantize function...
             this.InitialQuantizePixel(source[x, y]);
         }
     }
 }
示例#19
0
 public QuantizedImage Quantize(ImageBase image, int maxColors)
 {
     if (image == null){
         throw new ArgumentNullException();
     }
     int colorCount = NumUtils.Clamp(maxColors,1, 256);
     Clear();
     using (IPixelAccessor imagePixels = image.Lock()){
         Build3DHistogram(imagePixels);
         Get3DMoments();
         Box[] cube;
         BuildCube(out cube, ref colorCount);
         return GenerateResult(imagePixels, colorCount, cube);
     }
 }
        /// <inheritdoc/>
        protected override void Apply(
            ImageBase target,
            ImageBase source,
            Rectangle targetRectangle,
            Rectangle sourceRectangle,
            int startY,
            int endY)
        {
            float[,] kernelX = this.KernelX;
            float[,] kernelY = this.KernelY;

            ImageBase firstPass = new Image(source.Width, source.Height);
            this.ApplyConvolution(firstPass, source, sourceRectangle, startY, endY, kernelX);
            this.ApplyConvolution(target, firstPass, sourceRectangle, startY, endY, kernelY);
        }
示例#21
0
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            for (int y = rectangle.Y; y < rectangle.Bottom; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    Color color = source[x, y];

                    color.R = (byte)(255 - color.R);
                    color.G = (byte)(255 - color.G);
                    color.B = (byte)(255 - color.B);

                    target[x, y] = color;
                }
            }
        }
示例#22
0
文件: OAMEditor.cs 项目: MetLob/tinke
        public OAMEditor(string langxml, Bank bank, SpriteBase sprite, ImageBase image, PaletteBase palette)
        {
            InitializeComponent();
            this.bank = bank;
            numOAM.Maximum = bank.oams.Length - 1;
            numOffset.Maximum = (bank.data_size == 0)
                ? image.Tiles.Length / (0x20 << (int)sprite.BlockSize) - 1
                : bank.data_size / (0x20 << (int)sprite.BlockSize) - 1;

            preview = true;
            this.sprite = sprite;
            this.image = image;
            this.palette = palette;

            Read_Language(langxml);
        }
示例#23
0
        /// <inheritdoc/>
        public void Encode(ImageBase image, Stream stream)
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            int rowWidth = image.Width;

            int amount = (image.Width * 3) % 4;
            if (amount != 0)
            {
                rowWidth += 4 - amount;
            }

            using (BinaryWriter writer = new BinaryWriter(stream))
            {
                BmpFileHeader fileHeader = new BmpFileHeader
                {
                    Type = 19778, // BM
                    Offset = 54,
                    FileSize = 54 + (image.Height * rowWidth * 3)
                };

                WriteHeader(writer, fileHeader);

                BmpInfoHeader infoHeader = new BmpInfoHeader
                {
                    HeaderSize = 40,
                    Height = image.Height,
                    Width = image.Width,
                    BitsPerPixel = 24,
                    Planes = 1,
                    Compression = BmpCompression.RGB,
                    ImageSize = image.Height * rowWidth * 3,
                    ClrUsed = 0,
                    ClrImportant = 0
                };

                WriteInfo(writer, infoHeader);

                this.WriteImage(writer, image);

                writer.Flush();
            }
        }
示例#24
0
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            byte temp = 0;

            for (int y = rectangle.Y; y < rectangle.Bottom; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    Color color = source[x, y];

                    temp = (byte)(color.R * _cr + color.G * _cg + color.B * _cb);

                    color.R = temp;
                    color.G = temp;
                    color.B = temp;

                    target[x, y] = color;
                }
            }
        }
示例#25
0
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            byte temp = 0;

            for (int y = rectangle.Y; y < rectangle.Bottom; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    Color color = source[x, y];

                    temp = (byte)(0.299 * color.R + 0.587 * color.G + 0.114 * color.B);

                    color.R = (byte)((temp > 206) ? 255 : temp + 49);
                    color.G = (byte)((temp < 14) ? 0 : temp - 14);
                    color.B = (byte)((temp < 56) ? 0 : temp - 56);

                    target[x, y] = color;
                }
            }
        }
示例#26
0
        public void Encode(ImageBase image, Stream stream, BmpBitsPerPixel bitsPerPixel)
        {
            if (image == null || stream == null)
            {
                throw new ArgumentNullException();
            }
            bmpBitsPerPixel = bitsPerPixel;
            int rowWidth = image.Width;

            // TODO: Check this for varying file formats.
            int amount = (image.Width * (int)bmpBitsPerPixel) % 4;

            if (amount != 0)
            {
                rowWidth += 4 - amount;
            }

            // Do not use IDisposable pattern here as we want to preserve the stream.
            EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Little, stream);
            int           bpp         = (int)bmpBitsPerPixel;
            BmpFileHeader fileHeader  = new BmpFileHeader {
                Type     = 19778,             // BM
                Offset   = 54,
                FileSize = 54 + image.Height * rowWidth * bpp
            };
            BmpInfoHeader infoHeader = new BmpInfoHeader {
                HeaderSize   = 40,
                Height       = image.Height,
                Width        = image.Width,
                BitsPerPixel = (short)(8 * bpp),
                Planes       = 1,
                ImageSize    = image.Height * rowWidth * bpp,
                ClrUsed      = 0,
                ClrImportant = 0
            };

            WriteHeader(writer, fileHeader);
            WriteInfo(writer, infoHeader);
            WriteImage(writer, image);
            writer.Flush();
        }
示例#27
0
        /// <summary>
        /// Writes the graphics control extension to the stream.
        /// </summary>
        /// <typeparam name="T">The pixel format.</typeparam>
        /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
        /// <param name="image">The <see cref="ImageBase{T,TP}"/> to encode.</param>
        /// <param name="writer">The stream to write to.</param>
        /// <param name="transparencyIndex">The index of the color in the color palette to make transparent.</param>
        private void WriteGraphicalControlExtension <T, TP>(ImageBase <T, TP> image, EndianBinaryWriter writer, int transparencyIndex)
            where T : IPackedVector <TP>
            where TP : struct
        {
            // TODO: Check transparency logic.
            bool           hasTransparent = transparencyIndex > -1;
            DisposalMethod disposalMethod = hasTransparent
                ? DisposalMethod.RestoreToBackground
                : DisposalMethod.Unspecified;

            GifGraphicsControlExtension extension = new GifGraphicsControlExtension()
            {
                DisposalMethod    = disposalMethod,
                TransparencyFlag  = hasTransparent,
                TransparencyIndex = transparencyIndex,
                DelayTime         = image.FrameDelay
            };

            // Reduce the number of writes.
            byte[] intro =
            {
                GifConstants.ExtensionIntroducer,
                GifConstants.GraphicControlLabel,
                4 // Size
            };

            writer.Write(intro);

            PackedField field = new PackedField();

            field.SetBits(3, 3, (int)extension.DisposalMethod); // 1-3 : Reserved, 4-6 : Disposal

            // TODO: Allow this as an option.
            field.SetBit(6, false);                      // 7 : User input - 0 = none
            field.SetBit(7, extension.TransparencyFlag); // 8: Has transparent.

            writer.Write(field.Byte);
            writer.Write((ushort)extension.DelayTime);
            writer.Write((byte)(extension.TransparencyIndex == -1 ? 255 : extension.TransparencyIndex));
            writer.Write(GifConstants.Terminator);
        }
示例#28
0
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            double pixel = 0, contrast = (100.0 + _contrast) / 100.0;

            for (int y = rectangle.Y; y < rectangle.Bottom; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    Color color = source[x, y];

                    pixel  = color.R / 255.0;
                    pixel -= 0.5;
                    pixel *= contrast;
                    pixel += 0.5;
                    pixel *= 255;
                    pixel  = pixel.RemainBetween(0, 255);

                    color.R = (byte)pixel;

                    pixel  = color.G / 255.0;
                    pixel -= 0.5;
                    pixel *= contrast;
                    pixel += 0.5;
                    pixel *= 255;
                    pixel  = pixel.RemainBetween(0, 255);

                    color.G = (byte)pixel;

                    pixel  = color.B / 255.0;
                    pixel -= 0.5;
                    pixel *= contrast;
                    pixel += 0.5;
                    pixel *= 255;
                    pixel  = pixel.RemainBetween(0, 255);

                    color.B = (byte)pixel;

                    target[x, y] = color;
                }
            }
        }
示例#29
0
        /// <inheritdoc/>
        public virtual QuantizedImage <TColor> Quantize(ImageBase <TColor> image, int maxColors)
        {
            Guard.NotNull(image, nameof(image));

            // Get the size of the source image
            int height = image.Height;
            int width  = image.Width;

            byte[]   quantizedPixels = new byte[width * height];
            TColor[] colorPalette;

            using (PixelAccessor <TColor> pixels = image.Lock())
            {
                // Call the FirstPass function if not a single pass algorithm.
                // For something like an Octree quantizer, this will run through
                // all image pixels, build a data structure, and create a palette.
                if (!this.singlePass)
                {
                    this.FirstPass(pixels, width, height);
                }

                // Collect the palette. Required before the second pass runs.
                colorPalette = this.GetPalette();

                if (this.Dither)
                {
                    // We clone the image as we don't want to alter the original.
                    using (Image <TColor> clone = new Image <TColor>(image))
                        using (PixelAccessor <TColor> clonedPixels = clone.Lock())
                        {
                            this.SecondPass(clonedPixels, quantizedPixels, width, height);
                        }
                }
                else
                {
                    this.SecondPass(pixels, quantizedPixels, width, height);
                }
            }

            return(new QuantizedImage <TColor>(width, height, colorPalette, quantizedPixels));
        }
示例#30
0
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            double pixel = 0, contrast = (100.0 + _contrast) / 100.0;

            for (int y = rectangle.Y; y < rectangle.Bottom; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    Color color = source[x, y];

                    pixel = color.R / 255.0;
                    pixel -= 0.5;
                    pixel *= contrast;
                    pixel += 0.5;
                    pixel *= 255;
                    pixel = pixel.RemainBetween(0, 255);

                    color.R = (byte)pixel;

                    pixel = color.G / 255.0;
                    pixel -= 0.5;
                    pixel *= contrast;
                    pixel += 0.5;
                    pixel *= 255;
                    pixel = pixel.RemainBetween(0, 255);

                    color.G = (byte)pixel;

                    pixel = color.B / 255.0;
                    pixel -= 0.5;
                    pixel *= contrast;
                    pixel += 0.5;
                    pixel *= 255;
                    pixel = pixel.RemainBetween(0, 255);

                    color.B = (byte)pixel;

                    target[x, y] = color;
                }
            }
        }
示例#31
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase <TPixel> source, Rectangle sourceRectangle)
        {
            using (ImageBase <TPixel> temp = new Image <TPixel>(source))
            {
                // Detect the edges.
                new SobelProcessor <TPixel>().Apply(temp, sourceRectangle);

                // Apply threshold binarization filter.
                new BinaryThresholdProcessor <TPixel>(this.Value).Apply(temp, sourceRectangle);

                // Search for the first white pixels
                Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0);

                if (rectangle == sourceRectangle)
                {
                    return;
                }

                new CropProcessor <TPixel>(rectangle).Apply(source, sourceRectangle);
            }
        }
        public override async Task <ImageBase> CacheHeroImage()
        {
            ImageBase img   = null;
            int       width = -1;

            foreach (ImageBase image in Images.FindAll(i => i.ImageType == SDK.Images.ImageType.Hero))
            {
                if (image.Width > width)
                {
                    img   = image;
                    width = image.Width;
                }
            }

            img ??= (await GetScreenshots()).FirstOrDefault();
            if (InternalPackage != null)
            {
                InternalPackage.HeroImageCache = img;
            }
            return(img);
        }
示例#33
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="ImageBase{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="ImageBase{TPixel}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        public void Encode <TPixel>(ImageBase <TPixel> image, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            // Cast to int will get the bytes per pixel
            short bpp          = (short)(8 * (int)this.bitsPerPixel);
            int   bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);

            this.padding = bytesPerLine - (image.Width * (int)this.bitsPerPixel);

            // Do not use IDisposable pattern here as we want to preserve the stream.
            EndianBinaryWriter writer = new EndianBinaryWriter(Endianness.LittleEndian, stream);

            BmpInfoHeader infoHeader = new BmpInfoHeader
            {
                HeaderSize   = BmpInfoHeader.Size,
                Height       = image.Height,
                Width        = image.Width,
                BitsPerPixel = bpp,
                Planes       = 1,
                ImageSize    = image.Height * bytesPerLine,
                ClrUsed      = 0,
                ClrImportant = 0
            };

            BmpFileHeader fileHeader = new BmpFileHeader
            {
                Type     = 19778, // BM
                Offset   = 54,
                FileSize = 54 + infoHeader.ImageSize
            };

            WriteHeader(writer, fileHeader);
            this.WriteInfo(writer, infoHeader);
            this.WriteImage(writer, image);

            writer.Flush();
        }
示例#34
0
        protected override void Apply(ImageBase target, ImageBase source, Rectangle rectangle, int startY, int endY)
        {
            var radius   = Radius >= 0 ? Radius : Math.Min(rectangle.Width, rectangle.Height) * 0.5;
            var radiusSq = radius * radius;
            var centerX  = (rectangle.Left + rectangle.Right) * 0.5;
            var centerY  = (rectangle.Top + rectangle.Bottom) * 0.5;
            var count    = offsetsX.Length;
            var inc      = 1.0 / count;

            for (int y = startY; y < endY; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    var a     = 0.0;
                    var color = source[x, y];

                    for (var i = 0; i < count; i++)
                    {
                        var cx = (x + offsetsX[i] - centerX);
                        var cy = (y + offsetsY[i] - centerY);

                        if (radiusSq > cx * cx + cy * cy)
                        {
                            a += inc;
                        }
                    }

                    if (a < 1.0)
                    {
                        color = new Color(
                            (byte)(color.R),
                            (byte)(color.G),
                            (byte)(color.B),
                            (byte)(a * color.A));
                    }

                    target[x, y] = color;
                }
            }
        }
示例#35
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase <TColor, TPacked> source, Rectangle sourceRectangle)
        {
            if (this.Image.Bounds.Size != this.Size)
            {
                this.Image = this.Image.Resize(this.Size.Width, this.Size.Height);
            }

            // Align start/end positions.
            Rectangle bounds = this.Image.Bounds;
            int       minX   = Math.Max(this.Location.X, sourceRectangle.X);
            int       maxX   = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
            int       minY   = Math.Max(this.Location.Y, sourceRectangle.Y);
            int       maxY   = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);

            float alpha = this.Alpha / 100F;

            using (PixelAccessor <TColor, TPacked> toBlendPixels = this.Image.Lock())
                using (PixelAccessor <TColor, TPacked> sourcePixels = source.Lock())
                {
                    Parallel.For(
                        minY,
                        maxY,
                        this.ParallelOptions,
                        y =>
                    {
                        for (int x = minX; x < maxX; x++)
                        {
                            Vector4 backgroundVector = sourcePixels[x, y].ToVector4();
                            Vector4 sourceVector     = toBlendPixels[x - minX, y - minY].ToVector4();

                            // Lerping colors is dependent on the alpha of the blended color
                            backgroundVector = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, alpha);

                            TColor packed = default(TColor);
                            packed.PackFromVector4(backgroundVector);
                            sourcePixels[x, y] = packed;
                        }
                    });
                }
        }
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            // Make sure we stop combining when the whole image that should be combined has been processed.
            if (rectangle.Right > _blendedImage.PixelWidth)
            {
                rectangle.Width = _blendedImage.PixelWidth - rectangle.Left;
            }

            if (rectangle.Bottom > _blendedImage.PixelHeight)
            {
                rectangle.Height = _blendedImage.PixelHeight - rectangle.Top;
            }

            for (int y = rectangle.Y; y < rectangle.Bottom; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    Color color = source[x, y], blendedColor = _blendedImage[x, y];

                    // combining colors is dependent o the alpha of the blended color
                    double alphaFactor = GlobalAlphaFactor != null ? GlobalAlphaFactor.Value : blendedColor.A / 255.0;

                    double invertedAlphaFactor = 1 - alphaFactor;

                    int r = (int) (color.R * invertedAlphaFactor) + (int) (blendedColor.R * alphaFactor);
                    int g = (int) (color.G * invertedAlphaFactor) + (int) (blendedColor.G * alphaFactor);
                    int b = (int) (color.B * invertedAlphaFactor) + (int) (blendedColor.B * alphaFactor);

                    r = r.RemainBetween(0, 255);
                    g = g.RemainBetween(0, 255);
                    b = b.RemainBetween(0, 255);

                    color.R = (byte)r;
                    color.G = (byte)g;
                    color.B = (byte)b;

                    target[x, y] = color;
                }
            }
        }
示例#37
0
        /// <summary>
        /// Encodes the data of the specified image and writes the result to
        /// the specified stream.
        /// </summary>
        /// <param name="image">The image, where the data should be get from.
        /// Cannot be null (Nothing in Visual Basic).</param>
        /// <param name="stream">The stream, where the image data should be written to.
        /// Cannot be null (Nothing in Visual Basic).</param>
        /// <exception cref="ArgumentNullException">
        ///     <para><paramref name="image"/> is null (Nothing in Visual Basic).</para>
        ///     <para>- or -</para>
        ///     <para><paramref name="stream"/> is null (Nothing in Visual Basic).</para>
        /// </exception>
        public void Encode(ImageBase image, Stream stream)
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");

            int rowWidth = image.PixelWidth;

            int amount = (image.PixelWidth * 3) % 4;

            if (amount != 0)
            {
                rowWidth += 4 - amount;
            }

            BinaryWriter writer = new BinaryWriter(stream);

            BmpFileHeader fileHeader = new BmpFileHeader();

            fileHeader.Type     = 19778;
            fileHeader.Offset   = 54;
            fileHeader.FileSize = 54 + image.PixelHeight * rowWidth * 3;
            Write(writer, fileHeader);

            BmpInfoHeader infoHeader = new BmpInfoHeader();

            infoHeader.HeaderSize   = 40;
            infoHeader.Height       = image.PixelHeight;
            infoHeader.Width        = image.PixelWidth;
            infoHeader.BitsPerPixel = 24;
            infoHeader.Planes       = 1;
            infoHeader.Compression  = BmpCompression.RGB;
            infoHeader.ImageSize    = image.PixelHeight * rowWidth * 3;
            infoHeader.ClrUsed      = 0;
            infoHeader.ClrImportant = 0;
            Write(writer, infoHeader);

            WriteImage(writer, image);

            writer.Flush();
        }
示例#38
0
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            PrepareFilter();

            if (_filter != null)
            {
                int filterSize = _filter.GetLength(0);

                for (int y = rectangle.Y; y < rectangle.Bottom; y++)
                {
                    for (int x = rectangle.X; x < rectangle.Right; x++)
                    {
                        double r = 0, g = 0, b = 0;

                        Color color = source[x, y];

                        for (int filterY = 0; filterY < filterSize; filterY++)
                        {
                            for (int filterX = 0; filterX < filterSize; filterX++)
                            {
                                int imageX = (x - filterSize / 2 + filterX + rectangle.Width) % rectangle.Width;
                                int imageY = (y - filterSize / 2 + filterY + rectangle.Height) % rectangle.Height;

                                Color tempColor = source[imageX, imageY];

                                r += tempColor.R * _filter[filterX, filterY];
                                g += tempColor.G * _filter[filterX, filterY];
                                b += tempColor.B * _filter[filterX, filterY];
                            }
                        }

                        color.R = (byte)(_factor * r + _bias).RemainBetween(0, 255);
                        color.G = (byte)(_factor * g + _bias).RemainBetween(0, 255);
                        color.B = (byte)(_factor * b + _bias).RemainBetween(0, 255);

                        target[x, y] = color;
                    }
                }
            }
        }
示例#39
0
        public void Apply(ImageBase target, ImageBase source, Rectangle rectangle)
        {
            // Make sure we stop combining when the whole image that should be combined has been processed.
            if (rectangle.Right > _blendedImage.PixelWidth)
            {
                rectangle.Width = _blendedImage.PixelWidth - rectangle.Left;
            }

            if (rectangle.Bottom > _blendedImage.PixelHeight)
            {
                rectangle.Height = _blendedImage.PixelHeight - rectangle.Top;
            }

            for (int y = rectangle.Y; y < rectangle.Bottom; y++)
            {
                for (int x = rectangle.X; x < rectangle.Right; x++)
                {
                    Color color = source[x, y], blendedColor = _blendedImage[x, y];

                    // combining colors is dependent o the alpha of the blended color
                    double alphaFactor = GlobalAlphaFactor != null ? GlobalAlphaFactor.Value : blendedColor.A / 255.0;

                    double invertedAlphaFactor = 1 - alphaFactor;

                    int r = (int)(color.R * invertedAlphaFactor) + (int)(blendedColor.R * alphaFactor);
                    int g = (int)(color.G * invertedAlphaFactor) + (int)(blendedColor.G * alphaFactor);
                    int b = (int)(color.B * invertedAlphaFactor) + (int)(blendedColor.B * alphaFactor);

                    r = r.RemainBetween(0, 255);
                    g = g.RemainBetween(0, 255);
                    b = b.RemainBetween(0, 255);

                    color.R = (byte)r;
                    color.G = (byte)g;
                    color.B = (byte)b;

                    target[x, y] = color;
                }
            }
        }
示例#40
0
        /// <summary>
        /// Encodes the data of the specified image and writes the result to
        /// the specified stream.
        /// </summary>
        /// <param name="image">The image, where the data should be get from.
        /// Cannot be null (Nothing in Visual Basic).</param>
        /// <param name="stream">The stream, where the image data should be written to.
        /// Cannot be null (Nothing in Visual Basic).</param>
        /// <exception cref="ArgumentNullException">
        /// <para><paramref name="image"/> is null (Nothing in Visual Basic).</para>
        /// <para>- or -</para>
        /// <para><paramref name="stream"/> is null (Nothing in Visual Basic).</para>
        /// </exception>
        public void Encode(ImageBase image, Stream stream)
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");

            // Write the png header.
            stream.Write(
                new byte[]
            {
                0x89, 0x50, 0x4E, 0x47,
                0x0D, 0x0A, 0x1A, 0x0A
            }, 0, 8);

            PngHeader header = new PngHeader();

            header.Width             = image.PixelWidth;
            header.Height            = image.PixelHeight;
            header.ColorType         = 6;
            header.BitDepth          = 8;
            header.FilterMethod      = 0;
            header.CompressionMethod = 0;
            header.InterlaceMethod   = 0;

            WriteHeaderChunk(stream, header);

            WritePhysicsChunk(stream, image);
            WriteGammaChunk(stream);

            if (IsWritingUncompressed)
            {
                WriteDataChunksFast(stream, image);
            }
            else
            {
                WriteDataChunks(stream, image);
            }
            WriteEndChunk(stream);

            stream.Flush();
        }
示例#41
0
        public void FileSave(ImageBase model, Context context)
        {
            var imagList = Request.Form["FileList"];

            if (string.IsNullOrEmpty(imagList))
            {
                return;
            }
            model.FileList = Newtonsoft.Json.JsonConvert.DeserializeObject <List <FileModel> >(imagList);

            var             type = model.FileList.Select(x => new { x.Type, x.SubType }).Distinct().ToList();
            List <Pictures> a    = new List <Pictures>();

            foreach (var item in type)
            {
                var fileList = context.Pictures.Where(x => x.RecordType == item.Type && x.RecordType2 == item.SubType && (x.RelationId == model.Id || x.RelationId == Guid.Empty));
                a.AddRange(fileList);
            }

            //Silinecekler
            var del = a.Where(x => model.FileList.Any(t => t.IsDeleted && t.Id == x.Id)).ToList();

            //dataDelete
            context.Pictures.RemoveRange(del);

            //Update
            var update = a.Where(x => model.FileList.Any(t => !t.IsDeleted && x.Id == t.Id)).ToList();

            foreach (var item in update)
            {
                var f = model.FileList.FirstOrDefault(x => x.Id == item.Id);
                if (item.RelationId == Guid.Empty)
                {
                    item.RelationId = model.Id;
                }
                item.RecordType2 = f.SubType;
                item.Title       = f.Title;
            }
            context.Pictures.UpdateRange(update);
        }
示例#42
0
        /// <inheritdoc/>
        public void Encode(ImageBase imageBase, Stream stream)
        {
            Guard.NotNull(imageBase, nameof(imageBase));
            Guard.NotNull(stream, nameof(stream));

            Image image = (Image)imageBase;

            // Write the header.
            // File Header signature and version.
            this.WriteString(stream, GifConstants.FileType);
            this.WriteString(stream, GifConstants.FileVersion);

            // Calculate the quality.
            int quality = this.Quality > 0 ? this.Quality : imageBase.Quality;
            quality = quality > 0 ? quality.Clamp(1, 256) : 256;

            // Get the number of bits.
            int bitDepth = this.GetBitsNeededForColorDepth(quality);

            // Write the LSD and check to see if we need a global color table.
            // Always true just now.
            this.WriteGlobalLogicalScreenDescriptor(image, stream, bitDepth);
            QuantizedImage quantized = this.WriteColorTable(imageBase, stream, quality, bitDepth);

            this.WriteGraphicalControlExtension(imageBase, stream);
            this.WriteImageDescriptor(quantized, quality, stream);

            if (image.Frames.Any())
            {
                this.WriteApplicationExtension(stream, image.RepeatCount, image.Frames.Count);
                foreach (ImageFrame frame in image.Frames)
                {
                    this.WriteGraphicalControlExtension(frame, stream);
                    this.WriteFrameImageDescriptor(frame, stream);
                }
            }

            // TODO: Write Comments extension etc
            this.WriteByte(stream, GifConstants.EndIntroducer);
        }
示例#43
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase <TColor, TPacked> source, Rectangle sourceRectangle)
        {
            ImageBase <TColor, TPacked> temp = new Image <TColor, TPacked>(source.Width, source.Height);

            temp.ClonePixels(source.Width, source.Height, source.Pixels);

            // Detect the edges.
            new SobelProcessor <TColor, TPacked>().Apply(temp, sourceRectangle);

            // Apply threshold binarization filter.
            new BinaryThresholdProcessor <TColor, TPacked>(this.Value).Apply(temp, sourceRectangle);

            // Search for the first white pixels
            Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0);

            if (rectangle == sourceRectangle)
            {
                return;
            }

            new CropProcessor <TColor, TPacked>(rectangle).Apply(source, sourceRectangle);
        }
示例#44
0
        public virtual QuantizedImage Quantize(ImageBase image, int maxColors)
        {
            if (image == null)
            {
                throw new ArgumentNullException();
            }
            int height = image.Height;
            int width  = image.Width;

            byte[]        quantizedPixels = new byte[width * height];
            List <Color2> palette;

            using (IPixelAccessor pixels = image.Lock()){
                if (!singlePass)
                {
                    FirstPass(pixels, width, height);
                }
                palette = GetPalette();
                SecondPass(pixels, quantizedPixels, width, height);
            }
            return(new QuantizedImage(width, height, palette.ToArray(), quantizedPixels, TransparentIndex));
        }
示例#45
0
        /// <summary>
        /// Writes the physical dimension information to the stream.
        /// </summary>
        /// <typeparam name="T">The pixel format.</typeparam>
        /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
        /// <param name="stream">The <see cref="Stream"/> containing image data.</param>
        /// <param name="imageBase">The image base.</param>
        private void WritePhysicalChunk <T, TP>(Stream stream, ImageBase <T, TP> imageBase)
            where T : IPackedVector <TP>
            where TP : struct
        {
            Image <T, TP> image = imageBase as Image <T, TP>;

            if (image != null && image.HorizontalResolution > 0 && image.VerticalResolution > 0)
            {
                // 39.3700787 = inches in a meter.
                int dpmX = (int)Math.Round(image.HorizontalResolution * 39.3700787D);
                int dpmY = (int)Math.Round(image.VerticalResolution * 39.3700787D);

                byte[] chunkData = new byte[9];

                WriteInteger(chunkData, 0, dpmX);
                WriteInteger(chunkData, 4, dpmY);

                chunkData[8] = 1;

                this.WriteChunk(stream, PngChunkTypes.Physical, chunkData);
            }
        }
示例#46
0
        private void WriteImage(EndianBinaryWriter writer, ImageBase image)
        {
            // TODO: Add more compression formats.
            int amount = (image.Width * (int)bmpBitsPerPixel) % 4;

            if (amount != 0)
            {
                amount = 4 - amount;
            }
            using (IPixelAccessor pixels = image.Lock()){
                switch (bmpBitsPerPixel)
                {
                case BmpBitsPerPixel.Pixel32:
                    Write32bit(writer, pixels, amount);
                    break;

                case BmpBitsPerPixel.Pixel24:
                    Write24bit(writer, pixels, amount);
                    break;
                }
            }
        }
        /// <inheritdoc/>
        protected override void OnApply(ImageBase <TPixel> source, Rectangle sourceRectangle)
        {
            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;

            // Align start/end positions.
            int minX = Math.Max(0, startX);
            int maxX = Math.Min(source.Width, endX);
            int minY = Math.Max(0, startY);
            int maxY = Math.Min(source.Height, endY);

            // Reset offset if necessary.
            if (minX > 0)
            {
                startX = 0;
            }

            if (minY > 0)
            {
                startY = 0;
            }

            using (PixelAccessor <TPixel> sourcePixels = source.Lock())
            {
                for (int y = minY; y < maxY; y++)
                {
                    int offsetY = y - startY;
                    for (int x = minX; x < maxX; x++)
                    {
                        int    offsetX          = x - startX;
                        TPixel sourceColor      = sourcePixels[offsetX, offsetY];
                        TPixel transformedColor = sourceColor.ToVector4().X >= this.Threshold ? this.UpperColor : this.LowerColor;
                        this.Diffuser.Dither(sourcePixels, sourceColor, transformedColor, offsetX, offsetY, maxX, maxY);
                    }
                }
            }
        }
        /// <inheritdoc/>
        protected override void OnApply(ImageBase <TPixel> source, Rectangle sourceRectangle)
        {
            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;

            // Align start/end positions.
            int minX = Math.Max(0, startX);
            int maxX = Math.Min(source.Width, endX);
            int minY = Math.Max(0, startY);
            int maxY = Math.Min(source.Height, endY);

            // Reset offset if necessary.
            if (minX > 0)
            {
                startX = 0;
            }

            if (minY > 0)
            {
                startY = 0;
            }

            byte[] bytes = new byte[4];
            for (int y = minY; y < maxY; y++)
            {
                int           offsetY = y - startY;
                Span <TPixel> row     = source.GetRowSpan(offsetY);

                for (int x = minX; x < maxX; x++)
                {
                    int    offsetX     = x - startX;
                    TPixel sourceColor = row[offsetX];
                    this.Dither.Dither(source, sourceColor, this.UpperColor, this.LowerColor, bytes, this.Index, offsetX, offsetY, maxX, maxY);
                }
            }
        }
示例#49
0
        /// <inheritdoc/>
        protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            int sourceY = sourceRectangle.Y;
            int sourceBottom = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX = sourceRectangle.Right;
            Rectangle bounds = this.toBlend.Bounds;
            float alpha = this.Value / 100f;

            Parallel.For(
                startY,
                endY,
                y =>
                {
                    if (y >= sourceY && y < sourceBottom)
                    {
                        for (int x = startX; x < endX; x++)
                        {
                            Color color = source[x, y];

                            if (bounds.Contains(x, y))
                            {
                                Color blendedColor = this.toBlend[x, y];

                                if (blendedColor.A > 0)
                                {
                                    // Lerping colors is dependent on the alpha of the blended color
                                    float alphaFactor = alpha > 0 ? alpha : blendedColor.A;
                                    color = Color.Lerp(color, blendedColor, alphaFactor);
                                }
                            }

                            target[x, y] = color;
                        }
                        this.OnRowProcessed();
                    }
                });
        }
示例#50
0
        protected override void Apply(ImageBase target, ImageBase source, Rectangle rectangle, int startY, int endY)
        {
            if (UseHsbSpace)
            {
                HsbColor tint = HsbColor.FromRgb(TintColor);

                for (int y = startY; y < endY; y++)
                {
                    for (int x = rectangle.X; x < rectangle.Right; x++)
                    {
                        Color color = source[x, y];

                        HsbColor hsb = HsbColor.FromRgb(color);

                        hsb.H  = tint.H;
                        hsb.A *= tint.A;

                        target[x, y] = hsb.ToRgb();
                    }
                }
            }
            else
            {
                for (int y = startY; y < endY; y++)
                {
                    for (int x = rectangle.X; x < rectangle.Right; x++)
                    {
                        Color color = source[x, y];

                        target[x, y] = new Color(
                            r: (byte)(color.R * TintColor.R / 255),
                            g: (byte)(color.G * TintColor.G / 255),
                            b: (byte)(color.B * TintColor.B / 255),
                            a: color.A);
                    }
                }
            }
        }
示例#51
0
        /// <summary>
        /// Collects the grayscale pixel data.
        /// </summary>
        /// <typeparam name="T">The pixel format.</typeparam>
        /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
        /// <param name="image">The image to encode.</param>
        private void CollectGrayscaleBytes <T, TP>(ImageBase <T, TP> image)
            where T : IPackedVector <TP>
            where TP : struct
        {
            // Copy the pixels across from the image.
            this.pixelData = new byte[this.width * this.height * this.bytesPerPixel];
            int stride = this.width * this.bytesPerPixel;

            using (IPixelAccessor <T, TP> pixels = image.Lock())
            {
                Parallel.For(
                    0,
                    this.height,
                    Bootstrapper.Instance.ParallelOptions,
                    y =>
                {
                    for (int x = 0; x < this.width; x++)
                    {
                        // Convert the color to YCbCr and store the luminance
                        // Optionally store the original color alpha.
                        int dataOffset  = (y * stride) + (x * this.bytesPerPixel);
                        Color source    = new Color(pixels[x, y].ToVector4());
                        YCbCr luminance = source;
                        for (int i = 0; i < this.bytesPerPixel; i++)
                        {
                            if (i == 0)
                            {
                                this.pixelData[dataOffset] = ((byte)luminance.Y).Clamp(0, 255);
                            }
                            else
                            {
                                this.pixelData[dataOffset + i] = source.A;
                            }
                        }
                    }
                });
            }
        }
示例#52
0
        /// <summary>
        /// Rotates the image 180 degrees clockwise at the centre point.
        /// </summary>
        /// <param name="target">The target image.</param>
        /// <param name="source">The source image.</param>
        private void Rotate180(ImageBase <TColor, TPacked> target, ImageBase <TColor, TPacked> source)
        {
            int width  = source.Width;
            int height = source.Height;

            using (PixelAccessor <TColor, TPacked> sourcePixels = source.Lock())
                using (PixelAccessor <TColor, TPacked> targetPixels = target.Lock())
                {
                    Parallel.For(
                        0,
                        height,
                        this.ParallelOptions,
                        y =>
                    {
                        for (int x = 0; x < width; x++)
                        {
                            int newX = width - x - 1;
                            int newY = height - y - 1;
                            targetPixels[newX, newY] = sourcePixels[x, y];
                        }
                    });
                }
        }
示例#53
0
        public static WriteableBitmap ToBitmap(ImageBase image)
        {
            Guard.NotNull(image, "image");
            var       bitmap = new WriteableBitmap(image.PixelWidth, image.PixelHeight);
            ImageBase temp   = image;

            byte[] pixels = temp.Pixels;
            int[]  raster = bitmap.Pixels;
            Buffer.BlockCopy(pixels, 0, raster, 0, pixels.Length);
            for (int i = 0; i < raster.Length; i++)
            {
                int   abgr = raster[i];
                int   a    = (abgr >> 24) & 0xff;
                float m    = a / 255f;
                int   argb = a << 24 |
                           (int)((abgr & 0xff) * m) << 16 |
                           (int)(((abgr >> 8) & 0xff) * m) << 8 |
                           (int)(((abgr >> 16) & 0xff) * m);
                raster[i] = argb;
            }
            bitmap.Invalidate();
            return(bitmap);
        }
示例#54
0
        public override void Write(string fileOut, ImageBase image, PaletteBase palette)
        {
            BinaryWriter bw = new BinaryWriter(File.OpenWrite(fileOut));

            bw.Write(scx.type);
            bw.Write(scx.unknown1);
            bw.Write(scx.unknown2);
            bw.Write(scx.unknown3);
            bw.Write(scx.unknown4);

            bw.Write((ushort)Width);
            bw.Write((ushort)Height);
            bw.Write(Map.Length * 2);
            bw.Write(Map.Length * 2);

            for (int i = 0; i < Map.Length; i++)
            {
                bw.Write(Actions.MapInfo(Map[i]));
            }

            bw.Flush();
            bw.Close();
        }
示例#55
0
        /// <inheritdoc/>
        public override void Apply(ImageBase <TColor, TPacked> target, ImageBase <TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
        {
            int startX  = targetRectangle.X;
            int endX    = targetRectangle.Right;
            int sourceX = sourceRectangle.X;
            int sourceY = sourceRectangle.Y;

            using (PixelAccessor <TColor, TPacked> sourcePixels = source.Lock())
                using (PixelAccessor <TColor, TPacked> targetPixels = target.Lock())
                {
                    Parallel.For(
                        startY,
                        endY,
                        this.ParallelOptions,
                        y =>
                    {
                        for (int x = startX; x < endX; x++)
                        {
                            targetPixels[x, y] = sourcePixels[x + sourceX, y + sourceY];
                        }
                    });
                }
        }
示例#56
0
        /// <inheritdoc/>
        public QuantizedImage Quantize(ImageBase imageBase)
        {
            // Get the size of the source image
            int height = imageBase.Height;
            int width = imageBase.Width;

            // Call the FirstPass function if not a single pass algorithm.
            // For something like an Octree quantizer, this will run through
            // all image pixels, build a data structure, and create a palette.
            if (!this.singlePass)
            {
                this.FirstPass(imageBase, width, height);
            }

            byte[] quantizedPixels = new byte[width * height];

            // Get the pallete
            List<Bgra32> palette = this.GetPalette();

            this.SecondPass(imageBase, quantizedPixels, width, height);

            return new QuantizedImage(width, height, palette.ToArray(), quantizedPixels);
        }
示例#57
0
        /// <summary>
        /// Applies the box filter kernel around one pixel.
        /// </summary>
        /// <param name="original">The original image to blur</param>
        /// <param name="target">The result</param>
        /// <param name="centerRow">Vertical coordinate of the result pixel</param>
        /// <param name="centerCol">Horizontal coordinate of the result pixel</param>
        protected virtual void Kernel(ImageBase original, ImageBase target, int centerRow, int centerCol)
        {
            int top    = Math.Max(0, centerRow - radius);
            int bottom = Math.Min(original.Height - 1, centerRow + radius);
            int left   = Math.Max(0, centerCol - radius);
            int right  = Math.Min(original.Width - 1, centerCol + radius);

            int   area          = (bottom - top + 1) * (right - left + 1);
            float normalization = 1.0f / area;

            for (int chan = 0; chan < original.NumChannels; ++chan)
            {
                float result = 0;
                for (int row = top; row <= bottom; ++row)
                {
                    for (int col = left; col <= right; ++col)
                    {
                        result += original.GetPixelChannel(col, row, chan) * normalization;
                    }
                }
                target.SetPixelChannel(centerCol, centerRow, chan, result);
            }
        }
        public void Resize(ImageBase source, ImageBase target, int width, int height)
        {
            byte[] newPixels = new byte[width * height * 4];

            double xFactor = (double)source.PixelWidth / width;
            double yFactor = (double)source.PixelHeight / height;

            int dstOffsetLine = 0;
            int dstOffset     = 0;

            int srcOffsetLine = 0;
            int srcOffset     = 0;

            byte[] sourcePixels = source.Pixels;

            for (int y = 0; y < height; y++)
            {
                dstOffsetLine = 4 * width * y;

                // Calculate the line offset at the source image, where the pixels should be get from.
                srcOffsetLine = 4 * source.PixelWidth * (int)(y * yFactor);

                for (int x = 0; x < width; x++)
                {
                    dstOffset = dstOffsetLine + 4 * x;
                    srcOffset = srcOffsetLine + 4 * (int)(x * xFactor);

                    newPixels[dstOffset + 0] = sourcePixels[srcOffset + 0];
                    newPixels[dstOffset + 1] = sourcePixels[srcOffset + 1];
                    newPixels[dstOffset + 2] = sourcePixels[srcOffset + 2];
                    newPixels[dstOffset + 3] = sourcePixels[srcOffset + 3];
                }
            }

            target.SetPixels(width, height, newPixels);
        }
示例#59
0
        /// <summary>
        /// Writes the graphics control extension to the stream.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="ImageBase{TPixel}"/> to encode.</param>
        /// <param name="metaData">The metadata of the image or frame.</param>
        /// <param name="writer">The stream to write to.</param>
        /// <param name="transparencyIndex">The index of the color in the color palette to make transparent.</param>
        private void WriteGraphicalControlExtension <TPixel>(ImageBase <TPixel> image, IMetaData metaData, EndianBinaryWriter writer, int transparencyIndex)
            where TPixel : struct, IPixel <TPixel>
        {
            // TODO: Check transparency logic.
            bool           hasTransparent = transparencyIndex < 255;
            DisposalMethod disposalMethod = hasTransparent
                ? DisposalMethod.RestoreToBackground
                : DisposalMethod.Unspecified;

            GifGraphicsControlExtension extension = new GifGraphicsControlExtension()
            {
                DisposalMethod    = disposalMethod,
                TransparencyFlag  = hasTransparent,
                TransparencyIndex = transparencyIndex,
                DelayTime         = metaData.FrameDelay
            };

            // Write the intro.
            this.buffer[0] = GifConstants.ExtensionIntroducer;
            this.buffer[1] = GifConstants.GraphicControlLabel;
            this.buffer[2] = 4;
            writer.Write(this.buffer, 0, 3);

            PackedField field = default(PackedField);

            field.SetBits(3, 3, (int)extension.DisposalMethod); // 1-3 : Reserved, 4-6 : Disposal

            // TODO: Allow this as an option.
            field.SetBit(6, false);                      // 7 : User input - 0 = none
            field.SetBit(7, extension.TransparencyFlag); // 8: Has transparent.

            writer.Write(field.Byte);
            writer.Write((ushort)extension.DelayTime);
            writer.Write((byte)extension.TransparencyIndex);
            writer.Write(GifConstants.Terminator);
        }
示例#60
0
        /// <summary>
        /// Rotates the image 90 degrees clockwise at the centre point.
        /// </summary>
        /// <param name="source">The source image.</param>
        private void Rotate90(ImageBase <TPixel> source)
        {
            int width  = source.Width;
            int height = source.Height;

            using (var targetPixels = new PixelAccessor <TPixel>(height, width))
            {
                Parallel.For(
                    0,
                    height,
                    this.ParallelOptions,
                    y =>
                {
                    Span <TPixel> sourceRow = source.GetRowSpan(y);
                    int newX = height - y - 1;
                    for (int x = 0; x < width; x++)
                    {
                        targetPixels[newX, x] = sourceRow[x];
                    }
                });

                source.SwapPixelsBuffers(targetPixels);
            }
        }