【问题标题】:Why this image converter doesn't work?为什么这个图像转换器不起作用?
【发布时间】:2013-01-17 03:30:20
【问题描述】:

我只是在 WPF 中玩图像,我编写了一个示例应用程序,它从硬盘加载图像,并且应该将每行中的前 100 个像素更改为红色。但它并没有这样做,而是生成的 iage 到处都有小红线。我相信代码中的某个地方,h 和 w 已更改,因此步幅不正确。但我找不到问题出在哪里。有任何帮助。

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestImageProcessing
{
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

class TransformImage
{
    public static BitmapSource Transform(BitmapImage input)
    {
        var red = new PixelColor() { Blue = 0, Green = 0, Red =255, Alpha =128 };
        var inputPixels = GetPixels(input);
        var outPixel = new PixelColor[inputPixels.GetLength(0), inputPixels.GetLength(1)];

        var output = new WriteableBitmap(input.PixelWidth, input.PixelHeight, input.DpiX, input.DpiY, input.Format, input.Palette);
        for (int h = 0; h < input.PixelHeight; h++)
        {
            for (int w = 0; w < input.PixelWidth; w++)
            {


               if (h < 100)
               {
                   outPixel[w, h] = red;
               }
               else
               {
                   outPixel[w, h] = inputPixels[w, h];
               }

            }
        }

        PutPixels(output, outPixel);
        return output;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct PixelColor
    {
        public byte Blue;
        public byte Green;
        public byte Red;
        public byte Alpha;
    }

    public static void PutPixels(WriteableBitmap bitmap, PixelColor[,] pixels)
    {
        int width = pixels.GetLength(0);
        int height = pixels.GetLength(1);
        bitmap.WritePixels(new Int32Rect(0, 0, width, height), pixels, width * 4, 0);
    }
    public static PixelColor[,] GetPixels(BitmapSource source)
    {
        if (source.Format != PixelFormats.Bgra32)
        {
            source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
        }
       PixelColor[,] pixels = new PixelColor[source.PixelWidth, source.PixelHeight];

        int stride = source.PixelWidth * ((source.Format.BitsPerPixel + 7) / 8);
        GCHandle pinnedPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);
        source.CopyPixels(
          new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight),
          pinnedPixels.AddrOfPinnedObject(),
          pixels.GetLength(0) * pixels.GetLength(1) * 4,
              stride);
        pinnedPixels.Free();
        return pixels;

    }
}
}

上面的部分代码来自这个帖子:Finding specific pixel colors of a BitmapImage

MainWindow.xaml:

<Window x:Class="TestImageProcessing.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="550" Width="725">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition Height="30px"/>
    </Grid.RowDefinitions>

    <Image x:Name="InImage" Grid.Row="0" VerticalAlignment="Top" Stretch="Uniform" />
    <Image x:Name="OutImage" Grid.Row="1" VerticalAlignment="Top" Stretch="Uniform" />
    <Button x:Name="Process" Content="Button"  Grid.Row="2"   Width="75" Click="Process_Click"/>




</Grid>
</Window>

MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TestImageProcessing
{


/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Process_Click(object sender, RoutedEventArgs e)
    {
        BitmapImage input= new BitmapImage(new Uri(@"C:\tmp\test.jpg"));
       InImage.Source=input;
        OutImage.Source = TransformImage.Transform(input);

    }
}
}

【问题讨论】:

    标签: wpf image


    【解决方案1】:

    您在 Transform 方法中创建的 WriteableBitmap 的像素格式应该是 PixelFormats.Bgra32,但您使用的是像素格式input 参数。


    如果要将像素存储在二维矩阵中,第一维代表的数量,第二维是的数量,所以你应该声明一个矩阵像素以这种方式:
    PixelColor[,] pixels = new PixelColor[Height, Width];
    

    注意你需要交换 widthheight


    已移除(不正确)

    【讨论】:

    • 谢谢。更改此设置会给出“输入数组不是有效等级”。错误。
    • @mans 我的错,抱歉。我忘记了 CopyPixels 不适用于多维数组,所以忽略那部分。
    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 2014-08-05
    相关资源
    最近更新 更多