图像哈希在UWP/C#中,图像在缩放和灰度化后水平重复

图像哈希在UWP/C#中,图像在缩放和灰度化后水平重复,c#,xaml,image-processing,hash,uwp,C#,Xaml,Image Processing,Hash,Uwp,我正在关注图像哈希 到目前为止,我取得了以下成就: 代码: 我做错了什么?处理后的图像有些可疑。。我从这里迷路了。。。我应该如何进行散列?有什么帮助吗?您的converttograyanc方法只需返回转换后的WriteableBitmap即可。循环中的像素转换代码也可以简化,并且该方法不需要对源和目标缓冲区进行操作。它还可以在适当的位置操纵像素值 private async Task<WriteableBitmap> ConvertToGrayAsync(WriteableBitma

我正在关注图像哈希

到目前为止,我取得了以下成就:

代码:


我做错了什么?处理后的图像有些可疑。。我从这里迷路了。。。我应该如何进行散列?有什么帮助吗?

您的
converttograyanc
方法只需返回转换后的WriteableBitmap即可。循环中的像素转换代码也可以简化,并且该方法不需要对源和目标缓冲区进行操作。它还可以在适当的位置操纵像素值

private async Task<WriteableBitmap> ConvertToGrayAsync(WriteableBitmap srcBitmap)
{
    var pixels = srcBitmap.PixelBuffer.ToArray();

    for (int i = 0; i < pixels.Length; i += 4)
    {
        var b = pixels[i];
        var g = pixels[i + 1];
        var r = pixels[i + 2];
        var f = (byte)(0.21 * r + 0.71 * g + 0.07 * b);
        pixels[i] = f;
        pixels[i + 1] = f;
        pixels[i + 2] = f;
    }

    var dstBitmap = new WriteableBitmap(srcBitmap.PixelWidth, srcBitmap.PixelHeight);

    using (var pixelStream = dstBitmap.PixelBuffer.AsStream())
    {
        await pixelStream.WriteAsync(pixels, 0, pixels.Length);
    }

    return dstBitmap;
}

您正在将图像复制到具有不同水平尺寸的图像中。您看到的影响不是重复,而是图像的多条水平线复制到结果中的一条直线上。验证入站图像和目标图像的尺寸和水平跨步。@WilliamJones感谢您的解释。但是我的目标图像尺寸是预定义的,我会尝试使用Lumia imaging sdk并应用灰度过滤器@肯塔基我想我早就应该使用Lumia Imaging SDK了。。谢谢精彩的。。谢谢你的回答。然而,缩放现在是一个问题。我将say
w
h
作为参数传递给
WriteableBitmap
的构造函数,但宽度始终保持原始值,高度保持
w
h
的较小值。如果我不调用
convertograyanc()
并直接返回位图,大小根本没有改变。请参阅我的编辑以了解另一个ProcessImageAsync方法,该方法还可以调整位图的大小。
<Image x:Name="myImage" Stretch="None" />
StorageFile userPickedFile = ...; //code ignored.
myImage.Source = await ProcessImageAsync(userPickedFile);
private async Task<WriteableBitmap> ConvertToGrayAsync(WriteableBitmap srcBitmap)
{
    var pixels = srcBitmap.PixelBuffer.ToArray();

    for (int i = 0; i < pixels.Length; i += 4)
    {
        var b = pixels[i];
        var g = pixels[i + 1];
        var r = pixels[i + 2];
        var f = (byte)(0.21 * r + 0.71 * g + 0.07 * b);
        pixels[i] = f;
        pixels[i + 1] = f;
        pixels[i + 2] = f;
    }

    var dstBitmap = new WriteableBitmap(srcBitmap.PixelWidth, srcBitmap.PixelHeight);

    using (var pixelStream = dstBitmap.PixelBuffer.AsStream())
    {
        await pixelStream.WriteAsync(pixels, 0, pixels.Length);
    }

    return dstBitmap;
}
private async Task<WriteableBitmap> LoadWriteableBitmapAsync(
    StorageFile file, int width, int height)
{
    using (var fileStream = await file.OpenReadAsync())
    using (var memoryStream = new InMemoryRandomAccessStream())
    {
        var decoder = await BitmapDecoder.CreateAsync(fileStream);
        var transform = new BitmapTransform
        {
            ScaledWidth = (uint)width,
            ScaledHeight = (uint)height,
            InterpolationMode = BitmapInterpolationMode.Cubic
        };
        var pixelData = await decoder.GetPixelDataAsync(
            BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform,
            ExifOrientationMode.RespectExifOrientation,
            ColorManagementMode.ColorManageToSRgb);
        var pixels = pixelData.DetachPixelData();

        var encoder = await BitmapEncoder.CreateAsync(
            BitmapEncoder.PngEncoderId, memoryStream);

        encoder.SetPixelData(
            BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight,
            (uint)width, (uint)height, 96, 96, pixels);

        await encoder.FlushAsync();
        memoryStream.Seek(0);

        var bitmap = new WriteableBitmap(width, height);
        await bitmap.SetSourceAsync(memoryStream);
        return bitmap;
    }
}
private async Task<WriteableBitmap> ProcessImageAsync(
    StorageFile file, int width, int height)
{
    return await ConvertToGrayAsync(
        await LoadWriteableBitmapAsync(file, width, height));
}