Функции обычно относятся к процедурному программированию. В ООП у вас есть методы, которые на самом деле являются функциями по своей природе, работают так же, как функции, но они всегда работают по отношению к некоторому объекту. Вы не можете объявить метод / функцию, не создав для нее класс, аналогично, вы всегда должны вызывать функции, используя их объект. Таким образом, подход к созданию функций и простому вызову их в OOP не работает одинаково. Вы должны связать их с классом здесь и обычно с конструктором для этого класса.
Позвольте мне показать вам это на примере. Предположим, что мы пишем код на C, который является процедурным языком, функция выглядит следующим образом:
int add(int a, int b){
return a+b;
}
Теперь для Java метод в ООП выглядит следующим образом,
class NumberAdder{
int num1;
int num2;
NumberAdder(int num1, int num2){
this.num1=num1;
this.num2=num2;
}
public int getSum(){
return num1+num2;
}
}
Я сделал что-то очень похожее на это прежде в Java, и я нашел, что класс PixelGrabber в java.awt.image пакете API чрезвычайно полезен (если не совершенно необходимый).
Дополнительно Вы определенно хотели бы проверить класс ColorConvertOp, который может выполнять попиксельное преобразование цветов данных в исходном изображении, и значения итогового цвета масштабируются с точностью до конечного изображения. Документация продолжает, что изображения могут даже быть тем же изображением, в этом случае, было бы довольно просто обнаружить, если они идентичны.
При обнаружении подобия необходимо использовать некоторую форму метода усреднения, как упомянуто в ответе на этот вопрос
Если Вы можете, также проверить Объем 2 главы 7 Базового Java Horstman (8-й редактор), потому что существует целый набор примеров на преобразованиях изображений и т.п., но снова, удостоверьтесь, что ввели по абсолютному адресу вокруг java.awt.image пакета, потому что необходимо найти, что у Вас есть почти все подготовленное к Вам :)
G'luck!
Вы могли также генерировать подпись MD5 файла и проигнорировать дублирующиеся записи. Не поможет Вам найти подобные изображения все же.
Я думал бы, что Вам не нужна библиотека изображений, чтобы сделать это - просто выборка содержания URL и сравнение этих двух потоков, поскольку массивы байтов должны сделать это.
Если, конечно, Вы не интересуетесь идентификацией подобных изображений также.
В зависимости от того, как подробный Вы хотите добраться с ним:
Независимо от того, если Вы хотите сделать все это, или не Вы должны:
Никакая потребность полагаться на любые специальные библиотеки обработки изображений, изображения являются просто байтами.
вычислите MD5s с помощью чего-то вроде этого:
MessageDigest m=MessageDigest.getInstance("MD5");
m.update(image.getBytes(),0,image.length());
System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16));
Поместите их в hashmap.
Хеширование уже предлагается и распознающий, идентичны ли два файла, очень легко, но Вы сказали пиксельный уровень. Если Вы хотите распознать два изображения, даже если они находятся в различных форматах (.png/.jpg/.gif/..) и даже если они масштабировались, я предлагаю: (использование библиотеки изображений и если изображение является средними/большими значками № 16x16):
Вы сделаете сумму различия всех серых пикселей обоих изображений, Вы получаете число, если различие <T, Вы считаете оба изображения идентичными
--
Посмотрите на класс MessageDigest. По существу Вы создаете экземпляр его, затем передаете его ряд байтов. Байты могли быть байтами, непосредственно загруженными из URL, если Вы знаете, что два изображения, которые являются "тем же", будут тем же самым файлом/потоком байтов. Или при необходимости, Вы могли создать BufferedImage из потока, затем вытащить пиксельные значения, что-то как:
MessageDigest md = MessageDigest.getInstance("MD5");
ByteBuffer bb = ByteBuffer.allocate(4 * bimg.getWidth());
for (int y = bimg.getHeight()-1; y >= 0; y--) {
bb.clear();
for (int x = bimg.getWidth()-1; x >= 0; x--) {
bb.putInt(bimg.getRGB(x, y));
}
md.update(bb.array());
}
byte[] digBytes = md.digest();
Так или иначе MessageDigest.digest () в конечном счете дает Вам массив байтов, который является "подписью" изображения. Вы могли преобразовать это в шестнадцатеричную строку, если это полезно, например, для включения HashMap или таблицы базы данных, например:
StringBuilder sb = new StringBuilder();
for (byte b : digBytes) {
sb.append(String.format("%02X", b & 0xff));
}
String signature = sb.toString();
Если содержание/изображение от двух URL дает Вам ту же подпись, то они - то же изображение.
Править: Я забыл упоминать, что при хешировании пиксельных значений Вы, вероятно, хотели бы включать размеры изображения в хеше также. (Только к подобной вещи - пишут два ints в 8-байтовый ByteBuffer, затем обновляют MessageDigest с соответствующим 8 массивами байтов.)
Другая вещь состоит в том, что кто-то упомянул, то, что MD5 не является коллизией-resistent. Другими словами, существует техника для построения нескольких последовательностей байта с тем же хешем MD5, не имея необходимость использовать метод проб и ошибок "грубой силы" (где в среднем, Вы ожидали бы должными быть пробовать о 2^64 или 16 миллиардов миллиардов файлов прежде, чем совершить нападки на коллизии). Это делает MD5 неподходящий, где Вы пытаетесь защитить от этой модели угрозы. Если Вы не обеспокоены случаем, где кто-то мог бы сознательно попытаться одурачить Вашу дублирующуюся идентификацию, и Вы просто взволнованы по поводу возможностей дублирующегося хеша "случайно", то MD5 прекрасен абсолютно. На самом деле это не прекрасно только, это на самом деле немного чрезмерно - как я говорю, в среднем, Вы ожидали бы один "ложный дубликат" приблизительно после 16 миллиардов миллиардов файлов. Или помещенный иначе, у Вас мог быть, скажем, миллиард файлов и шанс коллизии быть чрезвычайно близко к нулю.
Если Вы волнуетесь по поводу обрисованной в общих чертах модели угрозы (т.е. Вы думаете, что кто-то мог бы сознательно выделять процессорное время построению файлов для одурачивания системы), то решение состоит в том, чтобы использовать более сильный хеш. Java поддерживает SHA1 из поля (просто заменяют "MD5" "SHA1"). Это теперь даст Вам, более длинные хеши (160 битов вместо 128 битов), но с современными знаниями делает нахождение коллизии неосуществимым.
Лично с этой целью я даже рассмотрел бы просто использование достойной 64-разрядной хеш-функции. Это все еще позволит десяткам миллионов изображений быть по сравнению с шансом близко к нулю положительной лжи.
Осмотрите заголовки ответа и опросите значение Завершающего тега HTTP-заголовка, если существующий. (RFC2616: Завершающий тег) Они, возможно, то же для идентичных изображений, прибывающих из Вашего целевого веб-сервера. Это вызвано тем, что значение Завершающего тега часто является дайджестом сообщения как MD5, который позволил бы Вам использовать в своих интересах уже завершенные вычисления веб-сервера.
Это может потенциально позволить Вам даже не загружать изображение!
for each imageUrl in myList
Perform HTTP HEAD imageUrl
Pull ETag value from request
If ETag is in my map of known ETags
move on to next image
Else
Download image
Store ETag in map
Конечно, Завершающий тег должен присутствовать, и в противном случае хорошо идея является тостом. Но возможно у Вас есть получение по запросу с администраторами веб-сервера?