Изменить цвет пикселя java

Обновлено: 05.07.2024

if (args.length > 0) s = args[0];

Управлять проигрыванием файла можно с помощью событий. Событие класса LineEvent происходит при открытии, OPEN, и закрытии, CLOSE, потока, при начале, START, и окончании, STOP, проигрывания. Характер события отмечается указанными константами. Соответствующий интерфейс LineListener описывает только один метод update ().

В MIDI-файлах хранится последовательность (sequence) команд для секвен-сора (sequencer) — устройства для записи, проигрывания и редактирования MlDI-последовательности, которым может быть физическое устройство или программа. Последовательность состоит из нескольких дорожек (tracks), на которых записаны MIDI-события (events). Каждая дорожка загружается в своем канале (channel). Обычно дорожка содержит звучание одного музыкального инструмента или запись голоса одного исполнителя или запись нескольких исполнителей, микшированную синтезатором (synthesizer).

Листинг 15.17. Проигрывание MIDI-последовательности

public void play(String file)

File f = new File(file);

// Получаем секвенсор по умолчанию

Sequencer sequencer = MidiSystem.getSequencerО;

// Проверяем, получен ли секвенсор

if (sequencer = null)

System.err.println("Sequencer is not supported");

// Получаем MIDI-последовательность из файла

Sequence seq = MidiSystem.getSequence(f);

// Направляем последовательность в секвенсор

// Здесь надо сделать задержку на время проигрывания,

// а затем остановить:

public static void main(String[] args)

if (args.length > 0) s = args[0];

Синтез и запись звука в Java 2

Синтез звука заключается в создании MIDI-последовательности — объекта класса sequence — каким-либо способом: с микрофона, линейного входа, синтезатора, из файла, или просто создать в программе, как это делается в листинге 15.18.

Сначала создается пустая последовательность одним из двух конструкторов:

Sequence(float divisionType, int resolution)

Sequence(float divisionType, int resolution, int numTracks)

Первый аргумент divisionType определяет способ отсчета моментов (ticks) MIDI-событий — это одна из констант:

  • PPQ (Pulses Per Quarter note) — отсчеты замеряются в долях от длительности звука в четверть;
  • SMPTE_24, SMPTE_25, SMPTE_so, SMPTE_30DROP (Society of Motion Picture and Television Engineers) — отсчеты в долях одного кадра, при указанном числе кадров в секунду.

Второй аргумент resolution задает количество отсчетов в указанную единицу, например,

Sequence seq = new Sequence)Sequence.PPQ, 10);

задает 10 отсчетов в звуке длительностью в четверть.

Третий аргумент numTracks определяет количество дорожек в MIDI-после-довательности.

Потом, если применялся первый конструктор, в последовательности создается одна или несколько дорожек:

Track tr = seq.createTrack() ;

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

Track[] trs = seq.getTracks();

ShortMessage msg = new ShortMessage();

rasg.setMessage(ShortMessage.NOTEJDN, 60, 93);

Далее создается MIDI-событие:

MidiEvent me = new MidiEvent

Наконец, событие заносится на дорожку:

Указанные действия продолжаются, пока все дорожки не будут заполнены всеми событиями. В листинге 15.18 это делается в цикле, но обычно MIDI-события создаются в методах обработки нажатия клавиш на обычной или специальной MIDI-клавиатуре. Еще один способ — вывести на экран изображение клавиатуры и создавать MIDI-собьгшя в методах обработки нажатий кнопки мыши на этой клавиатуре.

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

write(Sequence in, int type, File out)

write(Sequence in, int type, OutputStream out)

Второй аргумент type задает тип MIDI-файла, который лучше всего определить для заданной последовательности seq статическим методом getMidiFiieTypes(seq). Данный метод возвращает массив возможных типов. Надо воспользоваться нулевым элементом массива, ,Все это. показало в листинге 15.18.

Листинг 15.18. Создание MIDI-последовательности нот звукоряда

public Sequence synth()

Sequence seq = null;

// Последовательность будет отсчитывать по 10

// MIDI-событий на Звук длительйостью в четверть

seq = new Sequence(Sequence.PPQ, 10);

// Создаем в последовательности одну дорожку

Track tr = seq.createTrack();

for (int k = 0; k < 100; k++)

ShortMessage msg = new ShortMessage();

// Пробегаем MIDI-ноты от номера 10 до 109

msg.setMessage(ShortMessage.NOTE_ON, 10+k, 93);

// Будем проигрывать ноты через каждые 5 отсчетов

tr.add(new MidiEvent(msg, 5*k));

> catch (Exception e)

System, err.printing "From synth(): "+e);

public void play (Sequence seq)

Sequencer sequencer = MidiSystem.getSequencer();

if (sequencer = null)

System.err.println("Sequencer is not supported");

int[] type = MidiSystem.getMidiFileTypes(seq);

MidiSystem.write(seq, type[0], new File("gammas.mid"));

System.err.println("From play(): " + e);

public static void main(String[] args)(

К сожалению, объем книги не позволяет коснуться темы о работе с синтезатором (synthesizer), микширования звука, работы с несколькими инструментами и прочих возможностей Java Sound API. В документации SUN J2SDK, в каталоге docs\guide\sound\prog_guide, есть подробное руководство программиста, а в каталоге demo\sound\src лежат исходные тексты синтезатора, использующего Java Sound API.

Изменить цвет каждого пикселя в изображении java

Java: считывание изображения по пикселям и преобразование в оттенки серого с помощью простого метода градации серого

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

// Я также меняю третий параметр 0 на другой атрибут. но все равно не работает. все это черное. есть предложения?

  • 1 Можете ли вы привести пример того, что вы установили для третьего параметра?
  • Какой класс image ?
  • изображение - это bufferedImage, и я помещаю его в рамку. я хочу изменить частичную прозрачность изображения

Третий параметр - значение ARGB в 32 бита. Это изложено в битовой форме как:

См. Javadoc для BufferedImage.setRGB (при условии, что вы используете BufferedImage, ваш вопрос на самом деле не говорит . )

Устанавливает пиксель в этом BufferedImage на указанное значение RGB. Предполагается, что пиксель находится в цветовой модели RGB по умолчанию, TYPE_INT_ARGB и цветовом пространстве sRGB по умолчанию. Для изображений с IndexColorModel выбирается индекс с ближайшим цветом

  • Если вы используете тип изображения, который поддерживает прозрачность, важно, чтобы вы установили альфа 255 означает полностью непрозрачный, 0 - полностью прозрачный.

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

К счастью, в экземплярах java.awt.Color есть метод getRGB (), поэтому вы можете использовать

Вот полный рабочий пример, возможно, вы можете сравнить со своим кодом:

  • Спасибо за ответы. Я использую BufferedImage и стараюсь по-твоему. но это тоже не работает. Я использую черное изображение (изображение со всем черным фоном).
  • Можете ли вы опубликовать свой код для создания буферизованного изображения и отображения его?
  • @HuazheYin Я добавил полностью рабочий пример, показывающий красный цвет, я не видел полностью черной проблемы, которую вы описываете .

Ну, третий параметр - это цвет в RGB, поэтому он будет черным, если вы установите его на 0.

вот пример кода:

Я использую следующую форму:

Чтобы получить растр для BufferedImage, я делаю следующее:

Я провел некоторое тестирование производительности и не обнаружил, что объединение всех байтов значений цвета в одно число, чтобы иметь большое значение.

Также полезно знать технику, с помощью которой можно нарисовать непрозрачное изображение (например, RGB, а не ARGB) с альфа-значением.

Так, как основным языком в этом курсе стал язык Java. Покажу пример того как работать с файлами изображений в Java, чтобы вам не пришлось долго искать как это делать. Для других языков руководства можно найти в Интернете.

Того, что здесь будет показано вполне достаточно чтобы выполнить все лабы.

Итак, поехали.

BufferedImage - класс который представляет изображение, которое хранится в памяти. С помощью этого класса мы будем обрабатывать изображения.

Класс импортируется с пакета java.awt.image:

Для открытия изображения будем использовать два класса: File, ImageIO:

В параметра конструктора класса File, мы должны указать путь до файла. Путь может быть абсолютным, либо относитьтельно корня проекта. Можно открывать картинки с расширением jpg, png, bmp.

После этого в объекта image у нас будет храниться вся картинка, которую мы открыли. Мы можем получить у этой картинки значение любого пикселя в виде цвета в RGB. Чтобы получить цвет какого либо пикселя нам нужен класс Color:

Чтобы получить цвет из пикселя с координатами [20, 20] нужно написать:

Тут также показано как получить значение каждого канала(красный, зеленый, синий) этого цвета. Значения каналов находятся в диапазоне [0, 255].

Значения этих каналов мы будем использовать для обработки изображений. После обработки мы обычно получаем новые значения для каждого канала. Чтобы объединить три канала в один цвет, создаем новый объект класса Color:

Затем, мы можем установить этот цвет как цвет какого-либо пикселя в изображение:

После того, как мы обработали изображение, его нужно сохранить обратно в файл:

Вместо "jpg" можно использовать также "png" или "bmp".

Давайте для примера я напишу приложение, которое будет превращать исходное изображение в черно-белое, используя то, что написано в статье.

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

Преобразователь в черное белое

Возьмем для примера любое цветное изображение. Например:


Поместим его в корень проекта.

Запустив эту программу мы получим новую картинку в той же папке где и исходная картинка. И она должна быть такой:

Простейший путь обрабатывать данные с изображения – это брать каждый пиксель и изменять значение одного или нескольких из его каналов: красный, зеленый, синий и альфа (прозрачность), для краткости будем называть их R, G, B и A.
Пример: изменим какие-нибудь значения, например поменяем B и G:
Было rgb(100, 50, 30, 255) станет rgb(100, 30, 50, 255)
Манипуляцию как таковую можно представить простейшей callback-функцией. Для приведенного выше примера:

Здесь мы игнорируем альфа-канал, он нам не нужен и будет установлен равным 255.

image

image

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

Здесь мы используем переменную factor, с помощью которой будем задавать прозрачность изображения. Значение этой переменной будет возвращаться как альфа-канал:

image

и более сложный пример. Здесь мы будем дополнительно задавать, к какой части изображения применить прозрачность:

Если сделаем factor=111, получим:

image


this ссылается на созданный нами объект, который можно было немного увидеть. Он хранит в себе кое-какую нужную информацию, которая может пригодиться, как рассмотренном примере.

Холст

Рассмотрим структуру нашего холста. Начнем с конструктора:

Используем это, чтоб передать ссылку на элемент холста, находящийся где-нибудь на странице, а также url изображения.

Изображение должно быть в том же домене, где идет обработка его данных:

Конструктор создает объект new Image, и после загрузки изображение отрисовывается на холсте. Затем сохраняем некоторые вещи на будущее такие как context, объект image и оригинальные данные об изображении. ‘this’ – тот же самый, к которому манипулятор пикселями имеет доступ в примере выше.

Далее используем 3 простых метода для установки, получения и сброса данных изображения с холста:

Мозг всей обработки – это метод transform(). Он обрабатывает callback-вызов манипулятора пикселями и factor, который в сущности является конфигурационной настройкой для манипулятора. Затем он проходит по всем пикселям, передает значение olddata rgba-канала в callback-функцию и использует вернувшиеся значения как newdata. В конце newdata записывается на холст.

Довольно просто, не так ли? Единственный смущающий момент должен быть инкремент i+=4 в цикле. Данные возвращаются через getImageData().data как массив с 4 элементами для каждого пикселя.

Предположим, у изображения есть всего 2 пикселя: красный и синий, и нет прозрачности. Тогда данные для этого изображения выглядят как:

Callback

Дальнейший код просто показывает различные варианты callback-функции, и создает UI для их использования. Рассмотрим несколько из них:

Градации серого

Градации серого – это равное количество красного, синего, зеленого. Самый простой способ добиться этого – посчитать среднее значение:
var agv = (r + g + b) / 3;
Этого вполне достаточно. Но есть секретная формула для обработки фотографий с людьми, она устанавливает разную чувствительность для каналов:

image

Сепия

Простейший вариант: сделать серую версию и добавить немного цвета на неё – равного количества rgb для каждого пикселя. Я добавил 100 красного, 50 зеленого, но вы можете выбрать другие значения.

image

Вот другой вариант, который возможно и лучше, но мне не очень нравится:

image

Негатив

Вычтем значение каждого канала из 255 для получения негатива

image

Добавить шум. Это просто развлечение, берем случайное значение между –factor и factor и добавляем его к каждому каналу:

image

Ваш ход

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

Попробуйте, например, сделать изображение черно-белым (не градациями серого, а черно-белым, где каждый пиксель либо 0,0,0, либо 255,255,255).

В этом уроке мы рассмотрим несколько доступных библиотек обработки изображений и выполним простую операцию обработки изображений – загрузим изображение и нарисуем на нем фигуру.

Мы попробуем МОКРУЮ (и немного качающуюся) библиотеку, ImageJ, OpenIMAJ и двенадцать обезьян.

2. AWT

AWT-это встроенная библиотека Java, которая позволяет пользователю выполнять простые операции, связанные с отображением, такие как создание окна, определение кнопок и прослушивателей и так далее. Он также включает в себя методы, позволяющие пользователю редактировать изображения. Он не требует установки, так как поставляется с Java.

2.1. Загрузка изображения

Первое, что нужно сделать, это создать объект BufferedImage из изображения, сохраненного на нашем диске:

2.2. Редактирование изображения

В данном конкретном случае нам нужно Graphic 2D расширить ширину фигуры, чтобы сделать ее четко видимой. Мы достигаем этого, увеличивая его свойство s troke . Затем мы задаем цвет и рисуем прямоугольник таким образом, чтобы форма была в десяти пикселях от границ изображения:

2.3. Отображение изображения

Теперь, когда мы нарисовали что-то на нашем изображении, мы хотели бы показать это. Мы можем сделать это с помощью объектов библиотеки Swing. Сначала мы создаем JLabel объект, представляющий область отображения текста или/и изображения:

Затем добавьте наш JLabel в JPanel , который мы можем рассматривать как графического интерфейса на основе Java:

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

3. ImageJ

ImageJ-это программное обеспечение на базе Java, созданное для работы с изображениями. В нем довольно много плагинов, доступных здесь . Мы будем использовать только API, так как хотим выполнять обработку самостоятельно.

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

3.1. Зависимость Maven

Чтобы начать работу с ImageJ, просто добавьте зависимость в вашего проекта pom.xml файл:

Вы найдете самую новую версию в репозитории Maven .

3.2. Загрузка изображения

Чтобы загрузить изображение, вам нужно использовать метод open Image() static, из I J класс:

3.3. Редактирование изображения

Для редактирования изображения нам придется использовать методы из Image Processor object, прикрепленные к нашему ImagePlus объекту. Думайте об этом как о Графике объекте в AWT:

3.4. Отображение изображения

Вам нужно только вызвать show() метод Image Plus object:

4. OpenIMAJ

4.1. Зависимость Maven

Чтобы начать работу с OpenIMAJ, просто добавьте зависимость в вашего проекта pom.xml файл:

Вы найдете последнюю версию здесь .

4.1. Загрузка изображения

Чтобы загрузить изображение, используйте метод ImageUtilities.readMBF() :

MBF означает многополосное изображение с плавающей запятой (RGB в этом примере, но это не единственный способ представления цветов).

4.2. Редактирование изображения

Чтобы нарисовать прямоугольник, нам нужно определить его форму, которая представляет собой многоугольник, состоящий из 4 точек (верхний левый, нижний левый, нижний правый, верхний правый):

Как вы могли заметить, при обработке изображений ось Y меняется на противоположную. После определения формы нам нужно нарисовать ее:

Метод рисования принимает 3 аргумента: форма, толщина линии и значения канала RGB, представленные массивом Float .

4.3. Отображение изображения

Нам нужно использовать Утилиты отображения :

5. Изображение TwelveMonkeys

Библиотека TwelveMonkeys |/ImageIO предназначена для расширения Java ImageIO API, с поддержкой большего количества форматов.

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

По умолчанию Java поддерживает только эти пять форматов изображений: JPEG , PNG , BMP , WBMP , GIF .

Если мы попытаемся работать с файлом изображения в другом формате, наше приложение не сможет его прочитать и выдаст исключение NullPointerException при доступе к переменной BufferedImage .

Двенадцать обезьян добавляет поддержку следующих форматов: PNG , |/PSD , TIFF , HDR , TIFF , PCX , PICT , SGI , TGA , ICNS , ICO , CUR , Thumbs.db , SVG , WMF .

Для работы с изображениями в определенном формате нам необходимо добавить соответствующую зависимость , например imageio-jpeg или imageio-tiff .

Полный список зависимостей можно найти в документации Двенадцать обезьян .

Давайте создадим пример, который читает изображение .ico . Код будет выглядеть так же, как в разделе AWT , за исключением того, что мы откроем другое изображение:

Чтобы этот пример работал, нам нужно добавить зависимость Двенадцать обезьян , которая содержит поддержку .icon images, которая является зависимостью imageio-bmp , вместе с зависимостью imageio-core :

И это все! Встроенный ImageIO Java API автоматически загружает плагины во время выполнения. Теперь наш проект будет работать и с изображениями .ico .

6. Резюме

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

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

Читайте также: