Поворот битмапа на любой угол без использования getpixelsetpixel


Содержание

Алгоритм поворота битмапа на 90 градусов.

Всем привет.
Есть структура, в которой хранится высота ширина и само изображение, ввиде одномерного массива цветов покомпонентно (RGBA).
Нужен алгоритм поворота этого дела на 90 градусов по часовой стрелке.
Пока сделал так, но этот алгоритм не поворачивает, а транспонирует изображение.

я из исходников TFScript такую функцию упер (поворота на 90, 180, 270 градусов). Не знаю, корректно ли публиковать, пусть Mikle ее выложит если хочет.
Хотя в общем и самому можно догадаться — просто флипай и транспонируй за один проход.

Ну хотя ладно, вряд ли он будет возражать.
Вот его код на бейсике:

Вот мой перевод на паскаль

kipar
Спасибо!
Еще бы кто на понятный язык перевел)

bodja
Ну круто, только у меня bitmapData — это одномерный массив unsigned char*.
И нету у него getPixel и setPixel :)

kipar
> IndexDest, IndexSrc
так это двумерные массивы?

kipar
> SIZE div 2
А если размер не четный, что будет?

Misanthrope
> И нету у него getPixel и setPixel :)
Тогда представь их как обычные функции.

bodja
> Тогда представь их как обычные функции.
Я незнаю как

Misanthrope
да. двухмерные. Ну т.е. там трехмерный масиив текстур, можно из текстуры с номером IndexSrc поворачивать в текстуру IndexDest (в частности, они могут совпадать, ради этого и такой хитрый ход делается, иначе вариант bodja наверное предпочтительнее).
А, и они квадратные, хотя сходу я не вижу проблем переделать на прямоугольник, но тема про поворот в разделе выше меня несколько смущает.

Misanthrope
> А если размер не четный, что будет?
Хм, тоже проблема, видимо надо отдельно обработать. Я вообще исходил из размеров = степени двойки, иначе всякие бесшовные блюры усложняются.
Короче бери вариант bodja если у тебя in и out всегда разные массивы.

Улучшение скорости getpixel() и setpixel() на Android Bitmap

После того, как я заметил, насколько медленны getPixel и setPixel (не уверенный, какой из них, угадайте, оба не имеют турбонаддува), я быстро закодировал контейнер для Bitmap , который использует массив int[] для обработки битмап-операций.

Уже — его заметно быстрее, но этого недостаточно. Пожалуйста, вы могли бы посоветовать, как ускорить его?

Моя идея — следить за тем, что сделано «грязно» функциями setPixel и обновлять только эту часть Bitmap , когда вызывается getBitmap() . не понятно, как установить setPixels параметры (что-то со смещением и шагом, я думаю).

Также — любой более быстрый рецепт?

Спасибо за помощь!

Для таких простых функций, как setPixel / getPixel , служебные данные вызова функции относительно велики.

Было бы намного быстрее получить доступ к массиву pixels напрямую, а не через эти функции. Конечно, это означает, что вы должны сделать pixels общедоступным, что не очень приятно с точки зрения дизайна, но если вам абсолютно нужна вся производительность, которую вы можете получить, это путь.

Если этого еще недостаточно, подумайте о кодировании ваших операций растрового изображения в С++, используя NDK.

Другая альтернатива — использование android ndk. когда дело доходит до того, что у вас очень мало помощи, но это действительно увеличивает скорость.

Полный список


— создаем и меняем Bitmap
— разбираемся с density и mutable

В прошлом уроке мы научились читать Bitmap из файла. Сейчас рассмотрим способы его создания. Для этого есть несколько статических методов createBitmap. Все эти методы создания Bitmap можно разделить на три группы:

1) создание на основе другого Bitmap
2) создание из массива цветов
3) создание пустого Bitmap

Рассмотрим эти группы подробно.

Создание на основе другого Bitmap

Эти методы позволяют нам взять готовый Bitmap и скопировать его целиком или частично в новый bitmap. При этом поддерживаются преобразования с помощью матрицы.

В этой группе 4 метода.

параметры:
source – Bitmap-источник, от которого будем брать его часть
x,y – координаты точки, от которой будем отсчитывать часть
width, height – высота и ширина части
m – матрица для применения преобразований к взятой части
filter – если true, то будет включено сглаживание при scale- и rotate-преобразованиях матрицы (но это приведет к некоторой потере в производительности)

Этот метод возьмет от Bitmap-источника часть указанную координатами и размерами, применит к ней матрицу и фильтр и вернет нам как новый Bitmap. (Хотя, вовсе не обязательно это будет новый объект. Об этом подробнее в конце урока.)

Аналогичен методу 1, но без использования матрицы и фильтра. Т.е. просто возьмет указанную часть от Bitmap-источника.

Вызывает метод 2 с параметрами createBitmap(src, 0, 0, src.getWidth(), src.getHeight()). Т.е. указанная часть равна всему Bitmap.

В итоге мы получим тот же Bitmap, что и источник.

Вызывает метод 2 с параметрами createBitmap(src, 0, 0, src.getWidth(),src.getHeight(), m, filter). Т.е. указанная часть равна всему Bitmap. Но дополнительно применяется матрица m, где рассчитаны преобразования, чтобы новый Bitmap получился размерами dstWidth на dstHeight. Также, можно включить сглаживающий фильтр.

В итоге мы получим тот же Bitmap, что и источник, но он будет нужных нам размеров, заданных параметрами dstWidth и dstHeight.

Рассмотрим первый метод этой группы на примере.

Project name: P1581_BitmapCreate
Build Target: Android 4.4
Application name: BitmapCreate
Package name: ru.startandroid.develop.p1581bitmapcreate
Create Activity: MainActivity

В конструкторе DrawView создаем bitmapSource из стандартной иконки ic_launcher. Настраиваем матрицу на поворот и изменение размера. И создаем bitmap на основе bitmapSource. Берем кусок начиная с точки (0,0) размерами в половину ширины и половину высоты. Т.е. получается левая верхняя четверть изображения. Система возьмет эту часть, применит к ней матрицу и фильтр, и выдаст нам, как новый Bitmap.

В onDraw отображаем полученный Bitmap.

А так будет выглядеть полученный Bitmap если фильтр выключить

Создание из массива цветов

Эти методы позволяют нам создать Bitmap из готового массива цветов.

В этой группе 4 метода.

параметры:
display – объект DisplayMetrics, из которого Bitmap возьмет значение densityDpi (зачем он нужен, рассмотрим чуть позже)
colors – массив цветов, т.е. фактически массив пикселов из которых будет состоять созданный Bitmap
offset – отступ от начала colors при чтении его значений
stride – шаг, который будет использован для перемещения по массиву при смене строки Bitmap
width, height – размеры создаваемого Bitmap
config – конфигурация (используемый способ хранения данных о пикселах, мы их рассмотрели подробно на прошлом уроке)


Все параметры в целом понятны. Объясню немного подробнее про str >

Система создает Bitmap и заполняет его цветами из массива построчно. Но элементы массива она берет не все подряд, а высчитывает индекс первого элемента для каждой новой строки по формуле:
индекс первого элемента для каждой строки = (номер строки – 1) * stride

Т.е для первой строки – индекс первого элемента будет (1-1)*150 = 0. И начиная от него будут взяты цвета для первой строки, т.е. элементы [0-99], всего 100 элементов, т.к. ширина = 100). Для второй строки индекс первого элемента будет (2-1)*150 = 150. И для второй строки буду взяты цвета [150-249]. И т.д.

В итоге мы получаем Bitmap для которого сами указали значения цветов всех его пикселов.

Вызывает метод 1 с параметрами createBitmap(display, colors, 0, w >

Аналогичен методу 1, но без использования display.

Аналогичен методу 2, но без использования display.

Рассмотрим второй метод этой группы на примере. Перепишем класс DrawView:

В конструкторе DrawView создаем массив цветов количеством 300 * 300 = 90 000 элементов. Число выбрано такое, т.к. картинку мы будем создавать с шириной и высотой 300. Соответственно и цветов (читай пикселов) нам надо будет 300 * 300.

Илон Маск рекомендует:  Создание динамических форм с помощью javascript

Заполняем первую треть массива полупрозрачным красным цветом, вторую – зеленым, третью – синим.

Создаем bitmap, используя массив цветов и указав: ширину 300, высоту 300, конфигурацию — RGB_565.

Аналогично создаем bitmapAlpha, но конфигурацию укажем ARGB_8888.

В onDraw выводим оба Bitmap-а на канву.

Bitmap-ы получились в целом одинаковые, но первый проигнорил прозрачность красного цвета. Это произошло из-за того, что мы указали ему конфиг RGB_565. Он не поддерживает прозрачность и, при создании Bitmap, аlpha-компонент был отброшен. Сохранилась информация только о цвете. Зато этот Bitmap в два раза меньше весит в памяти.

Создание чистого Bitmap

Эти методы позволяют создать чистый Bitmap без каких-либо данных.

В этой группе 2 метода.

параметры:
display – объект DisplayMetrics, из которого Bitmap возьмет значение densityDpi (зачем он нужен, рассмотрим чуть позже)
width, height – размеры создаваемого Bitmap
config – конфигурация (используемый способ хранения данных о пикселах, мы их рассмотрели подробно на прошлом уроке)

Создается чистый Bitmap с указанными характеристиками.

Аналогичен методу 1, но без использования display

Рассмотрим второй метод этой группы на примере. Перепишем класс DrawView:

В конструкторе DrawView создаем чистый Bitmap размером 100х100.

Далее попробуем сами в нем что-нить нарисовать.

Методом setPixel ставим в нем три пиксела (20,20), (70,50) и (30,80) в красный цвет.


Методом setPixels можем менять пикселы не по одному, а массивом. Этот метод аналогичен методам создания Bitmap из массива цветов. Первые три параметра – это массив, offset и stride. Затем идут координаты точки, с которой начнем закраску (40,40), затем размер закрашиваемой области (10,15).

Как вы помните, канва – это всего лишь оболочка для Bitmap. Соответственно и наш Bitmap мы можем обернуть в канву и что-нить на нем с помощью этой канвы нарисовать. В нашем примере оборачиваем свежесозданный Bitmap в канву и рисуем на нем синий круг.

В onDraw выводим результат на экран.

Видим все фигуры, которые мы выводили.

Также, Bitmap имеет методы:

getPixel – получить значение цвета определенного пиксела

getPixels – получить значения цветов набора пикселов

getGenerationId – получить generationId, который меняется каждый раз, когда меняется Bitmap. Т.е. с его помощью можно отслеживать, что Bitmap был изменен.

Density

У Bitmap есть метод setDensity, туда мы можем передать density, к которому должна относиться эта картинка. Зачем это нужно я не очень понимаю, т.к. у нас один экран и density всегда, вроде как, один и тот же. Но штука интересная, рассмотрим на примере как оно работает и на что влияет.

В манифест для Activity добавьте строку:

В конструкторе DrawView создаем три Bitmap размерами 100х100. В bitmapIcon читаем иконку ic_launcher (она размером 48х48 при mdpi). Далее с помощью канвы рисуем иконку на все три Bitmap-а, но с небольшими нюансами.

В первом случае просто рисуем.

Во втором случае рисуем, а затем для bitmap2 ставим density в xhigh.

В третьем случае для bitmap3 ставим density в xhigh, а затем рисуем иконку.

В onDraw выводим все три Bitmap-а и для наглядности рисуем рамки размером 100х100 там же.

У меня на эмуляторе экран с density = mdpi. Если у вас density другое, то и результат будет другим.

Разбираемся, почему так получилось.

С первым случаем все понятно. Нарисовали иконку 48х48 и вывели на канву Bitmap размером 100х100.

Во втором случае мы нарисовали иконку на Bitmap, затем поменяли у него density на xhdpi, а затем уже вывели его на канву. Умная канва при этом спросила у Bitmap каков его density (xhdpi) и сравнила со своим (mdpi). Увидев, что Bitmap имеет density в два раза больший (xhdpi = 2 * mdpi) чем нужно, канва просто уменьшила в два раза стороны Bitmap (т.е. он стал 50х50, это видно на скрине) при выводе и тем самым компенсировала разницу в density.

В третьем случае мы сначала поменяли density на xhdpi, затем обернули его в канву (чтобы отличать от основной канвы, которая в onDraw, назовем ее bm3-канва). Эта bm3-канва автоматически подхватила density = xhdpi от bitmap3. Затем мы рисуем на bitmap3 с помощью bm3-канвы иконку. При этом bm3-канва определила, что иконка имеет density = mdpi (mdpi, т.к. это density устройства и оно всем ставится по умолчанию). В итоге получается, что density иконки в два раза меньше, чем density канвы. И канва, чтобы выровнять density просто увеличивает размер иконки при выводе. Т.к. иконка становится размером 96х96, и занимает почти весь Bitmap, который 100х100. Далее bitmap3 выводится на канву и здесь повторяются все те же рассуждения, что были во втором случае и bitmap в итоге выводится уменьшенным в два раза.

Основная мысль тут такова: канва сравнивает density – свой и у Bitmap, который она собирается рисовать. И если они различны, то выполняется подгонка размеров.

Если убрать из манифеста опцию hardwareAccelerated, то основная канва перестанет подгонять размер Bitmap. Почему так происходит, я не знаю.


Mutable

Свойство mutable означает, что Bitmap может быть изменен (через обертку канвой, методом setPixel, и т.п.). Соответственно immutable означает, что Bitmap не может быть изменен, т.е. он readOnly.

Из рассмотренных нами трех групп методов, третья группа возвращает mutable Bitmap, вторая – immutable Bitmap. А первая группа зависит от параметров и Bitmap-источника:
— если источник immutable и новый Bitmap будет являться точной копией исходника, то мы получим на выходе просто Bitmap-исходник. Т.е. это будет тот же Bitmap объект, и даже не его копия. И он останется immutable.
— если же источник mutable или новый Bitmap чем-то отличен от исходника, то мы получаем новый mutable Bitmap объект

Для определения mutable состояния у Bitmap используется метод isMutable.

На следующем уроке:

— разбираемся с BitmapFactory.Options
— сохраняем Bitmap в файл

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Как использовать GetPixel () для проверки разных позиций

У меня есть программа, которая должна использовать GetPixel, но в разных позициях, после прочтения одного значения и его оценки, она должна изменить позиции x, y и пересмотреть значения другой функции.
У меня есть текущий код:

Проблема в том, что GetPixel должен использовать X = 793 И Y = 866 для verde функцию, а затем использовать х = 803 у = 796 для amarelo функция

Решение

Простой ответ на ваш вопрос заключается в том, что вы можете позвонить GetPixel() несколько раз с разными координатами.

Также нет необходимости звонить GetDC(0) на каждой итерации цикла. Вы должны вызвать его один раз, прежде чем войти в цикл.

Однако, как говорится, ваши темы тратятся впустую. Ваш цикл блокируется в ожидании завершения первого потока перед запуском второго потока и блокируется в ожидании завершения второго потока перед переходом к следующей итерации цикла. Вы выполняете свой код в последовательном порядке, отказываясь от цели использования потоков, так что вы можете просто удалить потоки и вызвать функции напрямую:

Если вы хотите использовать потоки для параллельной обработки нескольких пикселей, это должно выглядеть примерно так:

Доступ к пикселям 24-битного растрового изображения без использования GetPixel()?

В настоящее время я ищу способ доступа и проверки отдельных пикселей скопированного растрового изображения из целевого окна без использования очень медленного метода GetPixel() . Учитывая, что memDC содержит копию растрового изображения в тот момент, когда был вызван BitBlt() , существует ли более быстрый способ пересечения отдельных пикселей и проверки их значений?

Создан 05 мар. 13 2013-03-05 20:06:39 Govind Parmar

1 ответ

При создании целевого растрового изображения с CreateDIBSection вы можете получить доступ к необработанным пикселей, вместо того, чтобы пройти через GetPixel .


E.g. если переданный вами BITMAPINFO указывает изображение 32-bpp (самый простой формат для интерпретации), вы можете получить доступ к произвольному пикселю, используя что-то вроде *(((LPDWORD)pBits) + (y * width) + x) .

Подробнее см. В документах для BITMAPINFOHEADER , чтобы узнать, как различные форматы бит-дифайтов выложены в памяти, и помните: а) что строки растровых изображений всегда выровнены по DWORD и b) вам нужно передать отрицательную высоту, down bitmap.

Илон Маск рекомендует:  Twitter + PHP + Codeigniter пишем twitter статус на PHP

И если вы не используете или не можете использовать CreateDIBSection , вы можете использовать GetDIBits , чтобы получить копию в растровом виде в формате DIB, который вы желаете. (Убедитесь, что растровое изображение выбрано из любого DC перед вызовом GetDIBits .)

Создан 05 мар. 13 2013-03-05 20:19:12 Jonathan Potter

Спасибо большое! Использование ‘GetDIBits’ теперь и мой алгоритм работают намного, намного быстрее, чем раньше! – Govind Parmar 05 мар. 13 2013-03-05 21:12:42

Точки в Паскале. SetPixel и PutPixel

Давайте поговорим о процедурах SetPixel(x, y, c) и PutPixel(x, y, c), которые выполняют одну и ту ж работу – закрашивают пиксель с координатами (x, y) цветом c. Но зачем это надо – закрашивать точки в разные цвета? Дело в том, что любое изображение состоит из точек (пикселей), каждая из которых имеет определенный цвет и свои координаты графическом окне Pascal. Во второй части статьи (см. внизу) мы покажем, как с помощью закрашивания пикселей нарисовать прямоугольник в Паскале, отрезок линии, круг и даже эллипс. А пока немного поговорим о геометрии.

Простейшим геометрическим объектом в математике является точка – нечто такое, не имеющее никакого размера, ни объема, ни площади. Правда, чтобы точку нарисовать, придется придать ей хоть какой-то размер (иначе её изобразить невозможно). Из точек построены все линии и фигуры, поверхности и тела – как на плоскости, так и в пространстве.

Чем отличается фигура от линии? Замкнутая линия на плоскости – это только граница, край, а фигура – часть плоскости, находящаяся внутри замкнутой линии. Примером линии является окружность, а соответствующая ей фигура – круг (часть плоскости).

Геометрическим телом называется множество точек в пространстве. Только не любое множество, а вся совокупность точек, отделенная от остального пространства какой-то границей, называемой поверхностью. Тело – это уже геометрическая фигура в пространстве. Примеры геометрического тела: куб, тетраэдр, шар, параллелепипед и др.

Создание изображения в Паскале реализуются с помощью растровой графики (точечной графики). Это значит, что наименьшим элементом рисунка является точка, называемая пикселем, которых представляют обычно в виде маленьких кружков или квадратиков. Если взять любое растровое изображение и сильно его увеличить, то можно увидеть отдельные области, из которых и состоит всё изображение – пиксели. Каждый пиксель имеет один цвет, и его уже нельзя разделить на меньшие части.

Другой важной характеристикой пикселя является его координаты в графическом окне, которые отсчитываются с левого верхнего угла вправо (ось OX) и вниз (ось OY). Раз так, то есть природная необходимость в подпрограммах, которые бы задавали цвет и координаты пикселя. Или, наоборот, при наличии рисунка в графическом окне было бы интересно узнать цвет пикселя с данными координатами.

SetPixel(x,y,c) – Эта процедура закрашивает пиксель с координатами (x, y) цветом c.

PutPixel(x,y,c) – Процедура, закрашивает пиксель с координатами (x, y) цветом c.

GetPixel(x,y)Возвращает цвет пикселя с координатами (x, y). Это уже функция (поскольку она что-то возвращает).

Причем первые две процедуры – SetPixel и PutPixel – являются равнозначными, и вы можете использовать любую из них. Чтобы продемонстрировать действие данных процедур, давайте напишем несколько простых программ. А вот функцией GetPixel(x,y) мы займемся на следующей странице. Но сначала укажем некоторые цветовые константы – названия стандартных цветов в PascalABC.Net:

Есть многие другие цветовые константы, но нам пока этого хватит.

Точка

Итак, попробуем нарисовать точку в PascalABC.Net с координатами, например, (300, 200), окрашенную в красный цвет. Чтобы мы её увидели, напишем возле неё слово «точка». Для этого создадим простую программу, подключив к ней модуль GraphABC:

Запустите приложение и в открывшемся графическом окне попробуйте найти маленькую красную точку чуть выше слева слова «точка». Это и есть пиксель с координатами (300, 200). Но точки создавать не интересно. Если бы мы нарисовали совокупность точек, идущих друг за другом, например, в горизонтальном направлении, то получили бы уже линию. Давайте так и сделаем.

Строим линию и жирную линию

Как построить линию в PascalABC.Net с помощью точек? Строить линию точками, каждый раз записывая процедуру SetPixel (или PutPixel), это не правильно, поскольку для этого пришлось бы записывать SetPixel огромное количество раз. Вместо этого построение можно организовать в цикле, в котором, шаг за шагом, точки сами будут выстраиваться в прямую линию.

Нарисуем линию от точки с координатами (100, 200) до точки (400, 200). Как видим, эта прямая будет параллельна оси OX (горизонтальна в нашем понимании), поскольку начало и конец отрезка имеют одинаковую координату y = 200. Таким образом, изменять придется только координату x – от 100 до 400, а для этого мы используем цикл for (с параметром) и процедуру SetPixel. Вот какая программа у нас вышла:


Созданная нами линия имеет толщину 1 пиксель. А чтобы нарисовать жирную линию, нужно, естественно, построить несколько линий рядом, накладывая их как бы одну на другую столько раз, какова толщина линии. Поскольку мы будем менять не только x, но и y, то здесь не обойтись без вложенного двойного цикла. Во внешнем цикле будем изменять y, а во внутреннем – координату x. Результат наших размышлений:

Граница прямоугольника

Как создать прямоугольник в PascalABC.Net с помощью точек? Поскольку рисовать отрезки мы уже научились, то для создания прямоугольника придется начертить всего четыре отрезка. Для этой цели достаточно задать координаты двух противоположных вершин прямоугольника – (x1, y1) и (x2, y2), где x2 > x1, y2 > y1, – а потом нарисовать четыре стороны (линии). Вот сам код с комментариями:

Закрашенный прямоугольник

А как закрасить прямоугольник в PascalABC.Net с помощью процедуры SetPixel или PutPixel? Для заливки прямоугольника каким-либо цветом используется тот же способ, что и при создании жирной линии: рисуются отрезки толщиной в 1 пиксель один за другим, пока их общая толщина не составит длину какой-то из сторон прямоугольника. Немного переформатировав код программы жирная линия, получим:

Рисуем круг

Как нарисовать круг в PascalABC.Net с помощью точек? Можно закрасить не весь прямоугольник, а какую-то его часть, например, круг, находящийся в середине квадрата с координатами противоположных вершин (x — r, y — r) и (x + r, y + r). Мы знаем, что уравнение окружности с центром в точке (x, y) и радиусом r выглядит так:

Но нам нужна не окружность, а круг, то есть «внутренность» окружности. Это вся совокупность точек (x, y), для которых расстояние до центра (x, y) не больше r:

Таким образом, чтобы закрасить круг в квадрате, необходимо его точки проверять на выполнение вышеуказанного неравенства: если оно истинно, то точки (x, y) закрашиваются. Вот соответствующая программа:

Рисуем закрашенный эллипс

А как нарисовать закрашенный эллипс в PascalABC.Net с помощью точек? Для этого используем эллипс, вписанный в прямоугольник с координатами противоположных вершин (x1, y1) и (x2, y2), для которых x2 > x1, y2 > y1. Сначала укажем, что уравнение эллипса с центром в начале координат и полуосями a и b выглядит так:

Но поскольку нам необходимо закрасить внутреннюю часть эллипса, то уравнение превратится в неравенство заполненного эллипса:

Стороны прямоугольника параллельны осям координат. Это означает, что координаты его центра равны полусумме координат противоположных вершин: x = (x1 + x2)/2, y = (y1 + y2)/2. А как найти a и b? Это стороны прямоугольника, разделенные на 2 (поэтому они называются полуосями): a = (x2 – x1)/2, b = (y2 – y1)/2. С учетом этого, неравенство заполненного эллипса приобретает вид:

(x – x) 2 /a 2 + (y – y) 2 /b 2 ≤ 1 .

Как видно на рисунках эллипса и круга, создание изображений с помощью закрашивания пикселей имеет существенный недостаток: границы рисунков выглядят не совсем плавными, как бы ступенчатыми. Оно и понятно: ведь пиксели – не точки в геометрическом понимании, которые не имеют размера, а все-таки небольшие квадратики или кружки. Тогда почему на всех фотографиях и рисунках нет ступенек? – спросите вы. Да потому, что там используется так называемое сглаживание. Суть этого метода в основном состоит в том, чтобы ближайшие к границе точки заменять более светлыми, или точнее, наиболее близкими по цвету с фоном, из-за чего создается эффект плавного перехода.

Бывает и обратная ситуация, когда нужно не сгладить изображение, сделав границы плавными (особенно это касается геометрических фигур), а как бы размыть. Делается это так: берем несколько соседних пикселей изображения, имеющих обычно разный цвет, и заменяем на пиксели одинакового цвета, совпадающем с цветом одного из пикселей. Получается картинка с очень увеличенными пикселями.

То же касается и видео: бывает необходимость закрыть лицо персонажа такими же увеличенными пикселями, или часть области заменить одним цветом. В специализированных программах для работы с графикой типа Gimp, Photoshop или Movavi показывается как редактировать видео и изображения, а смысл этого прост: замена пикселей одного цвета на пиксели другого цвета.

На этом пока всё, если что не понятно, задавайте вопросы в комментариях.

Илон Маск рекомендует:  HTML, JavaScript, PHP и MySQL. Джентльменский набор Web-мастера

пиксели доступа из 24-битных битовой карты, без использования GetPixel ()?

Я в настоящее время ищу способ доступа и проверить отдельные пиксели скопированного растрового изображения из целевого окна, без использования очень медленного GetPixel() метода. Учитывая , что memDC содержит копию растрового изображения в тот момент , который BitBlt() был назван, есть более быстрый способ обхода отдельных пикселей и проверить их значение?

При создании целевого растрового изображения с CreateDIBSection вы можете получить доступ к необработанным пикселям , вместо того , чтобы пройти GetPixel .

Например , если BITMAPINFO вы передаете определяет 32-BPP изображение (самый простой формат для интерпретации), вы можете получить доступ к произвольному пикселю , используя что — то вроде *( ((LPDWORD)pBits) + ( y * width ) + x) .

Смотрите документацию для BITMAPINFOHEADER Подробной информации о том , как различные форматы глубина цвета откладывается в памяти, и помнит) , что растровые строки всегда DWORD выровнены, и б) вы должны передать отрицательную высоту , чтобы создать сверху вниз растровое изображение.


А если не можете или не использовать CreateDIBSection , вы можете использовать , GetDIBits чтобы получить копию в памяти растрового изображения в формате DIB вы хотите. (Убедитесь , что битовая карта выбирается из любого DC перед вызовом GetDIBits .)

пиксели доступа из 24-битных битовой карты, без использования GetPixel ()?

Я в настоящее время ищу способ доступа и проверить отдельные пиксели скопированного растрового изображения из целевого окна, без использования очень медленного GetPixel() метода. Учитывая , что memDC содержит копию растрового изображения в тот момент , который BitBlt() был назван, есть более быстрый способ обхода отдельных пикселей и проверить их значение?

При создании целевого растрового изображения с CreateDIBSection вы можете получить доступ к необработанным пикселям , вместо того , чтобы пройти GetPixel .

Например , если BITMAPINFO вы передаете определяет 32-BPP изображение (самый простой формат для интерпретации), вы можете получить доступ к произвольному пикселю , используя что — то вроде *( ((LPDWORD)pBits) + ( y * width ) + x) .

Смотрите документацию для BITMAPINFOHEADER Подробной информации о том , как различные форматы глубина цвета откладывается в памяти, и помнит) , что растровые строки всегда DWORD выровнены, и б) вы должны передать отрицательную высоту , чтобы создать сверху вниз растровое изображение.

А если не можете или не использовать CreateDIBSection , вы можете использовать , GetDIBits чтобы получить копию в памяти растрового изображения в формате DIB вы хотите. (Убедитесь , что битовая карта выбирается из любого DC перед вызовом GetDIBits .)

Поворот битмапа на любой угол без использования getpixel/setpixel

artysite » 10.04.2007 (Вт) 10:10

Re: GetPixel и большие изображения

GSerg » 10.04.2007 (Вт) 10:12

Re: GetPixel и большие изображения

artysite » 10.04.2007 (Вт) 10:20

alibek » 10.04.2007 (Вт) 10:29

Re: GetPixel и большие изображения

GSerg » 10.04.2007 (Вт) 10:33

artysite » 10.04.2007 (Вт) 10:33

Чтобы потом обрабатывать изображения уже из массива, так быстрее получается

Re: GetPixel и большие изображения

artysite » 10.04.2007 (Вт) 10:36

GSerg » 10.04.2007 (Вт) 10:46

Ответ: Если вы хотите сделать Y, надо так и спрашивать, не предполагая заранее использование метода, который может вовсе не подходить. Вопросы такого вида часто задают те, кто не просто ничего не знает об X, но сбит с толку решаемой проблемой Y и слишком сконцентрирован на деталях своей конкретной ситуации. Обычно лучше игнорировать таких людей, пока они не сформулируют свою проблему лучше.

ZET74 » 10.04.2007 (Вт) 18:35

GSerg » 10.04.2007 (Вт) 18:43


CodeName33 » 11.04.2007 (Ср) 9:22

X-hacker » 12.04.2007 (Чт) 23:31

Код: Выделить всё Type BITMAPINFOHEADER
Type TRGB
B As Byte
G As Byte
R As Byte
End Type
Declare GetDIBits() ‘Не забудь BITMAPINFO заменить на BITMAPINFOHEADER
‘Сокращено в целях экономии места, юзай АпиВьювер

Private Sub GetPixels(IPicture As PictureBox, IWidth As Long, IHeight As Long, DestArray() As TRGB )
Dim BM As BITMAPINFOHEADER

With BM
.bmW > .bmHeight=IHeight
.bmSize=40
.bmSizeImage=IWidth*IHeight*3
.bmPlanes=1
End With

Redim DestArray(BM.bmWidth, BM.bmHeight)

Call GetDIBits(IPicture.hDC, IPicture.Image,0,0,IHeight,DestArray(0,0),BM,0)
End Sub

Вроде так, просто у мня нет возможности проверить, я в клубе сижу.
Если сильно надо, дам рабочую вместе с кодом.
А гадости вроде GetPixel и SetPixel просто !забудь!

CoTaskMemFree » 12.04.2007 (Чт) 23:36

ЗЫ. Интересно, что означает префикс I в аргументах функции GetPixels

keks-n » 13.04.2007 (Пт) 15:00

ZET74 » 15.04.2007 (Вс) 10:30

извините за тупость, разобраться не могу
Код: Выделить всё Public Type BITMAPINFOHEADER ’40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type

Public Type TRGB
B As Byte
G As Byte
R As Byte
End Type
‘Declare GetDIBits() ‘Íå çàáóäü BITMAPINFO çàìåíèòü íà BITMAPINFOHEADER
Public Declare Function GetDIBits Lib «gdi32» _
(ByVal aHDC As Long, _
ByVal hBitmap As Long, _
ByVal nStartScan As Long, _
ByVal nNumScans As Long, _
lpBits As Any, _
lpBI As BITMAPINFOHEADER, _
ByVal wUsage As Long) As Long

Public Declare Function GetDC Lib «user32» (ByVal hwnd As Long) As Long

‘Ñîêðàùåíî â öåëÿõ ýêîíîìèè ìåñòà, þçàé ÀïèÂüþâåð

Public Sub GetPixels(IPicture As PictureBox, IWidth As Long, IHeight As Long, DestArray() As TRGB)
Dim BM As BITMAPINFOHEADER

With BM
.bmW > .bmHeight = IHeight
.bmSize = 40
.bmSizeImage = IWidth * IHeight * 3
.bmPlanes = 1
End With

ReDim DestArray(BM.bmWidth, BM.bmHeight)

Call GetDIBits(IPicture.hDC, IPicture.Image, 0, 0, IHeight, DestArray(0, 0), BM, 0)
End Sub
1) в функции getdibits 7 параметров, а в функции getpixels она вызывается с восемью параметрами. что лишнее?
2) как вызывать функцию getpixels? что писать в IPicture и DestArray()
3) еще раз извините за тупость

X-hacker » 19.04.2007 (Чт) 15:50

Ноль там один лишний:
1 Контекст устройства
2 Указатель на битмап
3 Вроде первый индекс
4 Последний индекс(скольлко байт надо считать)
5 Указатель на массив или память
6 указатель на BitmapInfo
7 Способ применения (чаще всего ноль)

Кстати, если надо нарисовать точки, юзай SetPixelV() вместо SetPixel() ИМХО она быстрее!


Для вывода картинки юзай SetDIBitsToDevice()

keks-n » 20.04.2007 (Пт) 15:07

Поворот битмапа на любой угол без использования getpixel/setpixel

Submission failed. For some reason your suggested change could not be submitted. Please try again in a few minutes. And thank you for taking the time …

Bitmap.SetPixel(Int32, Int32, Color) Метод (System.Drawing .

Используйте метод SetPixel, чтобы задать цвет отдельного пикселя изображения программным способом. Use SetPixel method to set the color of an individual pixel in an image programmatically.

Getpixel API — social.msdn.microsoft.com

25.03.2006 · However, this person is trying to use an API call of the same name, which means that pinvoke is involved, and it’s a different API altogether. As an aside, GetPixel is really slow, if you need to get a lot of pixels, you’re better off writing a C# dll, given that VB.NET does not support unsafe blocks.

setpixel (Charles Forman) · GitHub

setpixel has 10 repositories available. Follow their code on GitHub.

ImageProcessor (ImageJ API)

This abstract class is the superclass for classes that process the four data types (byte, short, float and RGB) supported by ImageJ. An ImageProcessor contains the pixel data of a 2D image and some basic methods to manipulate it.

Unity — API скриптов: Texture2D.SetPixel

The Unity Manual helps you learn and use the Unity engine. With the Unity engine you can create 2D and 3D games, apps and experiences.

VB Graphics Programming: Part 2 (Beginning …

VB Graphics Programming: Part 2 (Beginning API) Basic API Pixel Routines Next, let’s discuss the basics of per-pixel graphics programming using the simple API routines of GetPixel and SetPixel / SetPixelV .

A fast way to work on Windows bitmap pixel …

05.06.2010 · This article shows a fast way to view and change pixel color data (Windows bitmaps) without using the GetPixel and SetPixel methods. Background. I spent a couple of months in trouble not knowing a fast way to edit images with C++ (I was using the Windows API functions GetPixel and SetPixel). I lost a couple of clients.

SetPixel — Точка

ImageField.SetPixel(X, Y, Color : Integer) Нарисовать точку. Метод ImageField.SetPixel рисует точку в координатах X,Y .

Выполняем проекты по API на заказ

Реклама Выполняем проекты по API на заказ. Коллектив специалистов. ?круглосуточно

Масло моторное TOTAL QUARTZ ENERGY

Реклама Масло моторное TOTAL QUARTZ ENERGY 9000 HKS 5w30 5 л Синтетика API SM ACEA A5 Hy

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL