/// <summary> /// Create an SHA1 hash from the image data (pixels only) to allow us to find /// duplicate images. Note that this ignores EXIF metadata, so the hash will /// find duplicate images even if the metadata is different. /// </summary> /// <param name="source"></param> /// <returns>String hash of the image data</returns> public static string GetHash(SKBitmap sourceBitmap) { string result = null; try { var hashWatch = new Stopwatch("HashImage"); var pixels = sourceBitmap.GetPixelSpan(); var hash = IncrementalHash.CreateHash(HashAlgorithmName.SHA1); for (int row = 0; row < sourceBitmap.Height; row++) { var rowPixels = pixels.Slice(row * sourceBitmap.RowBytes, sourceBitmap.RowBytes); byte[] rgbaBytes = MemoryMarshal.AsBytes(rowPixels).ToArray(); hash.AppendData(rgbaBytes); } result = hash.GetHashAndReset().ToHex(true); hashWatch.Stop(); Logging.LogVerbose($"Hashed image ({result}) in {hashWatch.HumanElapsedTime}"); } catch (Exception ex) { Logging.LogError($"Exception while calculating hash: {ex.Message}"); } return(result); }
private void InvertDraw(SKBitmap skBitmap, SKBitmap skBitmapInvert) { // Fast local copy var originalBytes = skBitmap.GetPixelSpan(); var invertBytes = skBitmapInvert.GetPixelSpan(); int total = originalBytes.Length / 4; for (int i = 0; i < total; i++) { // RGBA8888 int alphaByte = (i << 2) + 3; if (invertBytes[alphaByte] == 0) { continue; } // Set color var targetColor = SKColors.White; if (originalBytes[alphaByte - 1] == 255) { targetColor = SKColors.Black; } int x, y; y = Math.DivRem(i, skBitmapInvert.Width, out x); skBitmap.SetPixel(x, y, targetColor); } }
private static void CompareToSkiaResultsImpl(TestImageProvider <Rgba32> provider, IPath shape) { using Image <Rgba32> image = provider.GetImage(); image.Mutate(c => c.Fill(Color.White, shape)); image.DebugSave(provider, "ImageSharp", appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); using var bitmap = new SKBitmap(new SKImageInfo(image.Width, image.Height)); using var skPath = new SKPath(); foreach (ISimplePath loop in shape.Flatten()) { ReadOnlySpan <SKPoint> points = MemoryMarshal.Cast <PointF, SKPoint>(loop.Points.Span); skPath.AddPoly(points.ToArray()); } using var paint = new SKPaint { Style = SKPaintStyle.Fill, Color = SKColors.White, IsAntialias = true, }; using var canvas = new SKCanvas(bitmap); canvas.Clear(new SKColor(0, 0, 0)); canvas.DrawPath(skPath, paint); using var skResultImage = Image.LoadPixelData <Rgba32>(bitmap.GetPixelSpan(), image.Width, image.Height); skResultImage.DebugSave( provider, "SkiaSharp", appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); ImageSimilarityReport <Rgba32, Rgba32> result = ImageComparer.Exact.CompareImagesOrFrames(image, skResultImage); throw new Exception(result.DifferencePercentageString); }
private static byte[] BitmapToBytes(SKBitmap bmp) => bmp.GetPixelSpan().ToArray();
internal static string EncodeInternal(int xComponent, int yComponent, SKBitmap bitmap) => CoreBlurHashEncoder.Encode(xComponent, yComponent, bitmap.Width, bitmap.Height, bitmap.GetPixelSpan(), bitmap.RowBytes, PixelFormat.RGB888x);