Установите пиксели в растровом файле WPF в C#
В этом примере показано, как вы можете манипулировать пикселями в растровом файле WPF.
Одна из вещей, которые мне меньше всего нравятся в WPF, - это то, как Microsoft отбросила все, что мы узнали за годы работы с Visual Studio. Да, все в порядке, чтобы начать движение в новом направлении, но нет оснований игнорировать уроки, извлеченные через многолетний трудный опыт. Работа с растровыми изображениями является одной из областей, где WPF сделал именно это. Инструменты .NET не очень удобны для манипулирования пикселями изображения, но они лучше, чем один (обратите внимание, что я не говорю «одни»), предоставленные WPF.
В любом случае, чтобы создать растровое изображение в WPF, вы создаете объект WriteableBitmap. Затем вы создаете одномерный массив, содержащий информацию о необработанном пикселе для изображения, и вы используете метод WritePixels растрового изображения для копирования пиксельных данных в изображение. Следующий код показывает, как работает эта программа.
private void Window_Loaded(object sender, RoutedEventArgs e) { const int width = 240; const int height = 240; WriteableBitmap wbitmap = new WriteableBitmap( width, height, 96, 96, PixelFormats.Bgra32, null); byte[, ,] pixels = new byte[height, width, 4]; // Очистить до черного. for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { for (int i = 0; i < 3; i++) pixels[row, col, i] = 0; pixels[row, col, 3] = 255; } } // Синий. for (int row = 0; row < 80; row++) { for (int col = 0; col <= row; col++) { pixels[row, col, 0] = 255; } } // Зеленый. for (int row = 80; row < 160; row++) { for (int col = 0; col < 80; col++) { pixels[row, col, 1] = 255; } } // Красный. for (int row = 160; row < 240; row++) { for (int col = 0; col < 80; col++) { pixels[row, col, 2] = 255; } } // Скопируем данные в одномерный массив. byte[] pixels1d = new byte[height * width * 4]; int index = 0; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { for (int i = 0; i < 4; i++) pixels1d[index++]= pixels[row, col, i]; } } // Обновляем растровое изображение с возможностью записи с изображением colorArray. Int32Rect rect = new Int32Rect(0, 0, width, height); int stride = 4 * width; wbitmap.WritePixels(rect, pixels1d, stride, 0); // Создаем изображение для отображения растрового изображения. Image image = new Image(); image.Stretch = Stretch.None; image.Margin = new Thickness(0); grdMain.Children.Add(image); // Установите источник изображения. image.Source = wbitmap; }
Код начинается с создания WriteableBitmap. Он устанавливает разрешение растрового изображения на 96 пикселей на дюйм и использует формат Bgra32, поэтому растровое изображение использует 32 бита на пиксель для представления информации о синем, зеленом, красном и альфах (непрозрачности).
Обратите внимание на порядок: синий, зеленый, красный, альфа. Это порядок, в котором данные хранятся для каждого пикселя. Вероятно, это не тот порядок, который вы ожидаете.
Далее, чтобы упростить работу с пиксельными данными, программа создает трехмерный массив байтов. Каждая строка и столбец пикселя содержит 4 байта в массиве для хранения его синих, зеленых, красных и альфа-компонентов.
Затем код использует несколько циклов для установки данных байтового пикселя. Сначала он устанавливает цветовые компоненты каждого пикселя в 0 и его альфа-компоненты на 255 (непрозрачный). Затем он использует три петли для создания областей синего, зеленого и красного цветов.
Метод растрового изображения WritePixels ожидает одномерный массив в качестве параметра, поэтому код копирует трехмерные данные в одномерный массив.
Затем программа вызывает метод WritePixels растрового изображения, чтобы скопировать данные пикселов в растровое изображение. Прямоугольник указывает часть обновления растрового изображения. Параметр stride сообщает методу WritePixels, сколько байтов данных есть в строке в растровом изображении. Это просто ширина растрового изображения в пикселях, умноженное на количество байтов на пиксель. Конечным параметром является смещение в массиве в то место, где начинается копирование данных.
В этот момент битмап готов к использованию. Программа создает элемент управления Image, чтобы отобразить его, добавляет Изображение в основной элемент Grid программы и отображает растровое изображение в Изображение свойство source управления.