Изменение размера изображения Java - ближайший сосед

Я пытаюсь изменить размер изображения с помощью Java, и мне нужно получить точный эффект, который происходит при изменении размера с помощью Photoshop Nearest Neighbor (сохранить резкие края).

Дело в том, что я никогда не получаю точно такой же эффект...

Я пробовал следующие методы:

1) java-image-scale от mortennobel lib

resampleOp.setFilter(ResampleFilters.getBoxFilter());

это работает отлично, но оставляет некоторые артефакты на изображении, которых нет, когда это делает фотошоп.

2) Библиотека TwelveMonkeys для работы с изображениями. (вот ссылка на гитхаб) Тоже не сработало, PointFilter полностью уничтожает градиент внутри, а Box filter делает то же самое, что и mortennobel getBoxFilter.

3) AWT AffineTransform, это был худший вариант, совершенно нереальный ресайз.

Теперь я в замешательстве, размер ближайшего соседа фотошопа отличается от того, что означает имя, или все остальные библиотеки делают это неправильно (во втором случае, какая библиотека сделает это правильно?)

Вот изображения до и после, которые создает Photoshop.

введите здесь описание изображениявведите здесь описание изображения

А вот изображение, созданное с помощью get BoxFilter из mortennobel lib.

введите здесь описание изображения

Я немного увеличил изображения, чтобы вы могли видеть детали, на самом деле они меньше. Любая помощь очень ценится :) Я действительно застрял в этом.


person Avetis Zakharyan    schedule 21.09.2014    source источник
comment
Библиотека mortennobel использует блочный фильтр, и поэтому это не то, что вы просите — ближайший сосед. Вы не думали написать код самостоятельно? Итерация по необработанным пикселям изображения без какой-либо фильтрации не так уж сложна.   -  person Jongware    schedule 21.09.2014
comment
Хм.. Я думал, что коробочный фильтр и ближайший сосед одинаковы. Ну, я подумал об этом, но я подумал, что это может быть медленным, и, кроме того, должна быть библиотека, которая делает это правильно? Вместо причудливого фильтра используйте простой, это все, что я хочу. Я чувствую, что есть другое название для того, что делает Photoshop, и если бы я знал его, я бы нашел правильную библиотеку.   -  person Avetis Zakharyan    schedule 21.09.2014
comment
Возможно, вы захотите объяснить, насколько результаты использования RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR отличаются от того, чего вы хотите достичь (см. также today.java.net/pub/a/today/2007/04/03/ )   -  person Marco13    schedule 21.09.2014
comment
@ Marco13 Marco13, на самом деле это просто решило!!! Спасибо! Вы хотите опубликовать пример кода в качестве ответа, чтобы я мог проголосовать? или я могу сделать это сам, если хотите :)   -  person Avetis Zakharyan    schedule 21.09.2014
comment
Я мог только создать фрагмент, основанный на коде со связанного сайта, и догадаться о деталях, которые помогли решить проблему в вашем случае. Вы можете ответить на свой вопрос (иначе я постараюсь создать соответствующий ответ, но я думаю, что ваш был бы более точным)   -  person Marco13    schedule 21.09.2014
comment
Странно... Использование ResampleOp (из TwelveMonkeys/метод 2) с PointFilter должно дать точно такой же результат, как AffineTransformOp с VALUE_INTERPOLATION_NEAREST_NEIGHBOR (поскольку это то, что используется внутри). Если это не так, это следует считать ошибкой. о нет! ;-)   -  person Harald K    schedule 22.09.2014


Ответы (1)


Огромное спасибо Marco13 за указание на это! По-видимому, mortennobel lib не выполняет функцию Nearest Neighbour, вместо этого Graphics2D AWT может, если используется с подсказкой рендеринга RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR. Вот фрагмент кода, который работал у меня и давал точное изображение в фотошопе.

destinationBufferedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = destinationBufferedImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g2.drawImage(sourceBufferedImage, 0, 0, newWidth, newHeight, null);
g2.dispose();
person Avetis Zakharyan    schedule 22.09.2014