Image hashing in UWP/C#, the image repeats horizontally after scaling and graying

前端 未结 1 1888
星月不相逢
星月不相逢 2021-01-15 06:13

I am following this tutorial on image hashing.

So far I have achieved the following:

Code:

    private async Task ProcessI         


        
相关标签:
1条回答
  • 2021-01-15 06:32

    Your ConvertToGrayAsync method should simply return the converted WriteableBitmap. The pixel conversion code inside the loop could also be simplified, and the method does not need to operate on a source and destination buffer. It could as well manipulate the pixel values in place.

    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;
    }
    

    The following method loads a WriteableBitmap with a predefined size:

    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;
        }
    }
    

    Your ProcessImageAsync method would now look like this:

    private async Task<WriteableBitmap> ProcessImageAsync(
        StorageFile file, int width, int height)
    {
        return await ConvertToGrayAsync(
            await LoadWriteableBitmapAsync(file, width, height));
    }
    
    0 讨论(0)
提交回复
热议问题