/// <summary>Initializes a new instance of the <see cref="Bitmap32"/> class.</summary> /// <param name="width">Width in pixel.</param> /// <param name="height">Height in pixel.</param> public Bitmap32(int width, int height) { if (Loader == null) { throw new Exception("No valid IBitmap32Loader found!"); } bitmap = Loader.Create(width, height); }
/// <summary>Creates a bitmap instance from the specified Bitmap32.</summary> public static Bitmap ToGdiBitmap(this IBitmap32 other) { if (other is GdiBitmap32) { return(((GdiBitmap32)other).Bitmap); } using var ms = new MemoryStream(); other.Save(ms); ms.Position = 0; return(ToGdiBitmap(Image.FromStream(ms))); }
/// <summary> /// Converts a bitmap /// </summary> /// <param name="bitmap"></param> /// <returns></returns> public static SKBitmap Convert(IBitmap32 bitmap) { if (bitmap is SkiaBitmap32) { return(((SkiaBitmap32)bitmap).bitmap); } using (MemoryStream ms = new MemoryStream()) { bitmap.Save(ms); ms.Position = 0; return(SKBitmap.Decode(ms)); } }
/// <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())); } } }
/// <summary>Initializes a new instance of the <see cref="Bitmap32"/> class.</summary> /// <param name="bitmap"></param> public Bitmap32(IBitmap32 bitmap) { this.bitmap = bitmap; }
/// <summary> /// Disposes the image. /// </summary> public virtual void Dispose() { bitmap?.Dispose(); bitmap = null; }
/// <summary> /// Creates a new SkiaBitmap /// </summary> /// <param name="bitmap"></param> public SkiaBitmap32(IBitmap32 bitmap) : this(Convert(bitmap)) { }
/// <summary>Initializes a new instance of the <see cref="GdiBitmap32"/> class.</summary> /// <param name="bitmap"></param> public GdiBitmap32(IBitmap32 bitmap) : this(GdiBitmap32Extensions.ToGdiBitmap(bitmap)) { }