public static ImageHashUnknown CreateUnknownImageHash(FastBitmapHash hashData, Bitmap sourceImage, EImageHashType hashType) { Bitmap previewBitmap = new Bitmap(hashData.ContextBounds.Width, hashData.ContextBounds.Height); unsafe { BitmapData srcBitmapData = sourceImage.LockBits(hashData.ContextBounds, ImageLockMode.ReadOnly, sourceImage.PixelFormat); BitmapData dstBitmapData = previewBitmap.LockBits(new Rectangle(0, 0, previewBitmap.Width, previewBitmap.Height), ImageLockMode.WriteOnly, previewBitmap.PixelFormat); int srcBytesPerPixel = Image.GetPixelFormatSize(sourceImage.PixelFormat) / 8; int dstBytesPerPixel = Image.GetPixelFormatSize(previewBitmap.PixelFormat) / 8; Rectangle relativeInnerBounds = new Rectangle( hashData.SourceBounds.Left - hashData.ContextBounds.Left, hashData.SourceBounds.Top - hashData.ContextBounds.Top, hashData.SourceBounds.Width, hashData.SourceBounds.Height); for (int IdxY = 0; IdxY < hashData.ContextBounds.Height; IdxY++) { byte *srcPixels = (byte *)srcBitmapData.Scan0 + (IdxY * srcBitmapData.Stride); byte *dstPixels = (byte *)dstBitmapData.Scan0 + (IdxY * dstBitmapData.Stride); bool bInRangeY = (IdxY >= relativeInnerBounds.Top) && (IdxY <= relativeInnerBounds.Bottom); int SrcIdx = 0; int DstIdx = 0; for (int IdxPixel = 0; IdxPixel < hashData.ContextBounds.Width; IdxPixel++) { bool bInRange = bInRangeY && (IdxPixel >= relativeInnerBounds.Left) && (IdxPixel <= relativeInnerBounds.Right); int ColorDiv = bInRange ? 1 : 4; byte DefColor = bInRange ? (byte)255 : (byte)127; for (int IdxByte = 0; IdxByte < dstBytesPerPixel; IdxByte++) { dstPixels[DstIdx + IdxByte] = (IdxByte < srcBytesPerPixel) ? (byte)(srcPixels[SrcIdx + IdxByte] / ColorDiv) : DefColor; } SrcIdx += srcBytesPerPixel; DstIdx += dstBytesPerPixel; } } sourceImage.UnlockBits(srcBitmapData); previewBitmap.UnlockBits(dstBitmapData); } ImageHashUnknown newImageHash = new ImageHashUnknown { hashData = new ImageHashData(null, hashData.Hash, hashType, hashData.GuideOb), sourceImage = previewBitmap }; return(newImageHash); }
public static object FindMatchingHash(FastBitmapHash hashData, EImageHashType hashType, out int bestDistance, bool bDebugMode = false) { string debugDesc = bDebugMode ? hashData.Hash + " >> " : ""; int debugDescParts = 0; object bestMatchOb = null; bestDistance = -1; bool bIsLocked = PlayerSettingsDB.Get().IsLockedHash(hashData.Hash); foreach (ImageHashData hashInfo in PlayerSettingsDB.Get().customHashes) { if (hashInfo.Type == hashType) { bool bIsMatching = hashInfo.IsHashMatching(hashData.Hash, out int testDistance); if (bDebugMode) { debugDesc += ((hashType == EImageHashType.Card) ? ((TriadCard)hashInfo.Owner).ToShortString() : hashInfo.Owner.ToString()) + ":" + testDistance + ", "; debugDescParts++; } if (bIsLocked && testDistance != 0) { continue; } if (bIsMatching && (bestDistance < 0 || bestDistance > testDistance)) { bestDistance = testDistance; bestMatchOb = hashInfo.Owner; } } } if (bestDistance < 0) { foreach (ImageHashData hashInfo in ImageHashDB.Get().hashes) { if (hashInfo.Type == hashType) { bool bIsMatching = hashInfo.IsHashMatching(hashData.Hash, out int testDistance); if (bDebugMode) { debugDesc += ((hashType == EImageHashType.Card) ? ((TriadCard)hashInfo.Owner).ToShortString() : hashInfo.Owner.ToString()) + ":" + testDistance + ", "; debugDescParts++; } if (bIsLocked && testDistance != 0) { continue; } if (bIsMatching && (bestDistance < 0 || bestDistance > testDistance)) { bestDistance = testDistance; bestMatchOb = hashInfo.Owner; } } } } if (bDebugMode) { if (debugDescParts > 0) { debugDesc = debugDesc.Remove(debugDesc.Length - 2, 2); } debugDesc += " >> "; debugDesc += (bestMatchOb == null) ? "unknown" : ((hashType == EImageHashType.Card) ? ((TriadCard)bestMatchOb).ToShortString() : bestMatchOb.ToString()); Logger.WriteLine(debugDesc); } return(bestMatchOb); }