예제 #1
0
        /// <summary>
        /// Strech the bitmap without interpolation.
        /// </summary>
        public ARGBImageData StretchSimple(int width, int height)
        {
            if (height < 0)
            {
                height = Height;
            }

            if (width < 0)
            {
                width = Width;
            }

            var result      = new ARGBImageData(width, height);
            int targetIndex = 0;
            int moveX       = (Width << 10) / width;
            int moveY       = ((Height << 10) / height) - 1;

            int tY = 0;

            for (int y = 0; y < height; y++)
            {
                int tX = 0;
                for (int x = 0; x < width; x++)
                {
                    int sourceIndex = PositionToIndex(tX >> 10, tY >> 10);
                    result.Data[targetIndex++] = Data[sourceIndex];
                    tX += moveX;
                }
                tY += moveY;
            }
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Tile the bitmap.
        /// </summary>
        public ARGBImageData TileSimple(int width, int height)
        {
            if (height < 0)
            {
                height = Height;
            }

            if (width < 0)
            {
                width = Width;
            }

            var result = new ARGBImageData(width, height);
            int w      = Width;
            int h      = Height;

            int targetIndex = 0;

            for (int y = 0; y < height; y++)
            {
                int tY = y % h;
                for (int x = 0; x < width; x++)
                {
                    int tX          = x % w;
                    int sourceIndex = PositionToIndex(tX, tY);
                    result.Data[targetIndex++] = Data[sourceIndex];
                }
            }
            return(result);
        }
        /// <summary>
        /// Writes all data to a new <see cref="SKBitmap"/> instance
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception">Invalid length!</exception>
        public static SKBitmap ToSKBitmap(this ARGBImageData imageData)
        {
            SKImageInfo imgInfo = new SKImageInfo(imageData.Width, imageData.Height, SKColorType.Rgba8888, SKAlphaType.Unpremul);
            var         bitmap  = SKBitmap.FromImage(SkiaSharp.SKImage.Create(imgInfo));
            IntPtr      len;
            IntPtr      ptr     = bitmap.GetPixels(out len);
            int         byteLen = imageData.Data.Length * 4;

            if (len.ToInt32() != byteLen)
            {
                throw new Exception("Invalid length!");
            }
            Marshal.Copy(imageData.Data, 0, ptr, imageData.Data.Length);
            return(bitmap);
        }
예제 #4
0
 /// <summary>Creates a bitmap instance from the specified data.</summary>
 public Bitmap32 Create(ARGBImageData data)
 {
     return(new GdiBitmap32(data));
 }
예제 #5
0
        /// <summary>
        /// Tiles the outer border of the image and centers it.
        /// </summary>
        public ARGBImageData CenterTile(int width, int height)
        {
            if (height < 0)
            {
                height = Height;
            }

            if (width < 0)
            {
                width = Width;
            }

            bool l_TileY = height != Height;
            bool l_TileX = width != Width;

            // only tile one direction at the moment ! maybe later...
            if (l_TileX && l_TileY)
            {
                throw new NotSupportedException();
            }

            var result = new ARGBImageData(width, height);

            int heightCenterTop = (height - Height) / 2;

            if (l_TileY)
            {
                int heightCenterBottom = (height + Height) / 2;

                // fill top
                int sourceIndex = PositionToIndex(0, 0);
                for (int y = heightCenterTop; y >= 0; y--)
                {
                    int targetIndex = result.PositionToIndex(0, y);
                    Array.Copy(Data, sourceIndex, result.Data, targetIndex, Width);
                }

                // fill bottom
                sourceIndex = PositionToIndex(0, Height - 1);
                for (int y = heightCenterBottom; y < height; y++)
                {
                    int targetIndex = result.PositionToIndex(0, y);
                    Array.Copy(Data, sourceIndex, result.Data, targetIndex, Width);
                }
            }

            int widthCenterLeft = (width - Width) / 2;

            if (l_TileX)
            {
                int widthCenterRight = (width + Width) / 2;

                // fill left
                for (int y = 0; y < Height; y++)
                {
                    int sourceIndex = PositionToIndex(0, y);
                    for (int x = widthCenterLeft; x >= 0; x--)
                    {
                        int targetIndex = result.PositionToIndex(x, y);
                        result.Data[targetIndex] = Data[sourceIndex];
                    }

                    // fill right
                    sourceIndex = PositionToIndex(0, Height - 1);
                    for (int x = widthCenterRight; x < width; x++)
                    {
                        int targetIndex = result.PositionToIndex(x, y);
                        result.Data[targetIndex] = Data[sourceIndex];
                    }
                }
            }

            // copy center
            for (int y = 0; y < Height; y++)
            {
                int sourceIndex = PositionToIndex(0, y);
                int targetIndex = result.PositionToIndex(widthCenterLeft, y + heightCenterTop);
                Array.Copy(Data, sourceIndex, result.Data, targetIndex, Width);
            }

            return(result);
        }
예제 #6
0
        /// <summary>
        /// Creates a 32x32 fingerprint for the specified bitmap.
        /// </summary>
        /// <param name="bitmap">The bitmap.</param>
        /// <returns>Returns a fingerprint with 6 bits per pixel (32 px = 6144 bit = 768 byte = 1024 base32 chars).</returns>
        public static FingerPrint Create(IBitmap32 bitmap)
        {
            using (Bitmap32 thumb = bitmap.Resize(32, 32, ResizeMode.TouchFromInside))
            {
                ARGBImageData data = thumb.Data;
                using (var ms = new MemoryStream())
                {
                    // calculate fingerprint and distance matrix
                    var     writer         = new BitStreamWriter(ms);
                    float[] distanceMatrix = new float[16];
                    {
                        int  x = 0, y = 0;
                        ARGB last = 0;
                        foreach (ARGB pixel in data.Data)
                        {
                            if (++x > 15)
                            {
                                x = 0;
                                ++y;
                            }

                            int r = pixel.Red >> 6;
                            int g = pixel.Green >> 6;
                            int b = pixel.Blue >> 6;
                            writer.WriteBits(r, 2);
                            writer.WriteBits(g, 2);
                            writer.WriteBits(b, 2);

                            unchecked
                            {
                                int   i        = ((y << 1) & 0xC) + (x >> 2);
                                float distance = Math.Abs(pixel.GetDistance(last));
                                distanceMatrix[i] += distance;
                                last = pixel;
                            }
                        }
                    }

                    // normalize matrix
                    float maxDistance = distanceMatrix.Max();
                    for (int i = 0; i < distanceMatrix.Length; i++)
                    {
                        distanceMatrix[i] /= maxDistance;
                    }

                    // calculate blocks
                    uint[] blocks = new uint[4];
                    int[]  index  = new int[] { 0, 2, 8, 10 };
                    for (int i = 0; i < 4; i++)
                    {
                        int  idx        = index[i];
                        uint blockValue = (uint)(255 * distanceMatrix[idx]) << 24;
                        blockValue |= (uint)(255 * distanceMatrix[idx + 1]) << 16;
                        blockValue |= (uint)(255 * distanceMatrix[idx + 4]) << 8;
                        blockValue |= (uint)(255 * distanceMatrix[idx + 5]);
                        blocks[i]   = blockValue;
                    }

                    /*
                     * uint b1 = (uint)(uint.MaxValue * (distanceMatrix[0] + distanceMatrix[1]  + distanceMatrix[4] + distanceMatrix[5]) /4);
                     * uint b2 = (uint)(uint.MaxValue * (distanceMatrix[3] + distanceMatrix[2]  + distanceMatrix[7] + distanceMatrix[6]) / 4);
                     * uint b3 = (uint)(uint.MaxValue * (distanceMatrix[12] + distanceMatrix[13]  + distanceMatrix[8]  + distanceMatrix[9]) / 4);
                     * uint b4 = (uint)(uint.MaxValue * (distanceMatrix[15] + distanceMatrix[14]  + distanceMatrix[11] + distanceMatrix[10]) / 4);
                     */
                    return(new FingerPrint(32, blocks, ms.ToArray()));
                }
            }
        }
예제 #7
0
 /// <summary>Draws the specified image ontop of this one.</summary>
 /// <param name="other">The image to draw.</param>
 /// <param name="x">The x position.</param>
 /// <param name="y">The y position.</param>
 /// <param name="width">The width.</param>
 /// <param name="height">The height.</param>
 /// <param name="translation">The translation.</param>
 public virtual void Draw(ARGBImageData other, int x, int y, int width, int height, Translation?translation = null)
 {
     bitmap.Draw(other, x, y, width, height, translation);
 }
예제 #8
0
 /// <summary>Creates a bitmap instance from the specified data.</summary>
 public Bitmap32 Create(ARGBImageData data) => new GdiBitmap32(data);
예제 #9
0
 /// <summary>Draws the specified image ontop of this one.</summary>
 /// <param name="other">The image to draw.</param>
 /// <param name="x">The x position.</param>
 /// <param name="y">The y position.</param>
 /// <param name="width">The width.</param>
 /// <param name="height">The height.</param>
 /// <param name="translation">The translation.</param>
 public override void Draw(ARGBImageData other, int x, int y, int width, int height, Translation?translation = null)
 {
     Draw(other.ToSKBitmap(), x, y, width, height, translation);
 }
예제 #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SkiaBitmap32"/> class.
 /// </summary>
 /// <param name="data">The data.</param>
 public SkiaBitmap32(ARGBImageData data)
 {
     bitmap = data.ToSKBitmap();
 }
예제 #11
0
 /// <summary>Initializes a new instance of the <see cref="GdiBitmap32"/> class.</summary>
 /// <param name="data"></param>
 public GdiBitmap32(ARGBImageData data)
     : this(data.ToGdiBitmap())
 {
 }