2016-04-21 4 views
0

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

public class Main { 

public static int imgCtr = 1; 
public static File dest = new File("D:\\finalfinal"); 

public static void main(String[] args) throws Exception { 
    getContent("D:\\restoreFinal"); 
    getContent("D:\\restore1"); 
    getContent("D:\\restore2"); 
} 

public static String getExtension(String fileName) { 
    String extension = ""; 

    int i = fileName.lastIndexOf('.'); 
    if (i > 0) { 
     extension = fileName.substring(i + 1); 
    } 
    return extension; 
} 

public static boolean isImage(String extension) { 
    if (extension.equalsIgnoreCase("jpg") || extension.equalsIgnoreCase("jpeg") 
      || extension.equalsIgnoreCase("png")) 
     return true; 
    return false; 
} 

public static boolean compareImages(File a, File b) throws Exception { 
    FileInputStream fisA = new FileInputStream(a); 
    FileInputStream fisB = new FileInputStream(b); 
    byte contentA[] = new byte[(int) a.length()]; 
    byte contentB[] = new byte[(int) b.length()]; 
    fisA.read(contentA); 
    fisB.read(contentB); 
    String strA = new String(contentA); 
    String strB = new String(contentB); 
    fisA.close(); 
    fisB.close(); 
    return strA.equals(strB); 
} 

public static void getContent(String path) throws Exception { 
    File source = new File(path); 
    ArrayList<File> content = new ArrayList<File>(Arrays.asList(source.listFiles())); 
    while (!content.isEmpty()) { 
     File f = content.get(0); 
     if (isImage(getExtension(f.getName()))) { 
      if (dest.listFiles().length == 0) { 
       Path p = Paths.get(dest + "\\i" + imgCtr + "." + getExtension(f.getName())); 
       imgCtr++; 
       Files.move(f.toPath(), p); 
       System.out.println(imgCtr); 
      } else { 
       File[] alreadyThere = dest.listFiles(); 
       boolean match = false; 
       for (File cmp : alreadyThere) { 
        if (compareImages(f, cmp)) { 
         match = true; 
         break; 
        } 
       } 
       if (!match) { 
        Path p = Paths.get(dest + "\\i" + imgCtr + "." + getExtension(f.getName())); 
        imgCtr++; 
        Files.move(f.toPath(), p); 
        System.out.println(imgCtr); 
       } 
      } 
     } 
     content.remove(0); 
    } 
} 

}

Я написал сравнить изображение шпагатом сравнивает, потому что пиксель сравнения взял очень долго (было около 2k фотографий). Но проблема в том, что она копирует фотографию несколько раз без какой-либо разницы, которую я вижу. И я искал исходные папки, но он копирует фотографии произвольно, даже на фотографиях, у которых не было дубликатов, были дубликаты в папке назначения. Я сомневаюсь, что речь идет о методе сравнения, но я не мог найти свою ошибку.

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

+0

@MeetTitan Вы предлагаете сравнить куски пикселей. Я считаю, что все равно потребуется много времени, потому что у меня есть похожие фотографии, или это способ сравнить, скажем, 250x250 пикселей с быстрым способом без n^2 сложности – BrokenFrog

+2

Возможно, вы захотите просто начать с размера файла и контрольной суммы файла сравнение и только затем перейти на более интенсивное сравнение процессоров? –

+0

@AndreM это действительно хорошая идея. Спасибо, но как мне выполнить контрольную сумму фотографии. Должен ли я взять некоторые случайные пиксели или хеш строку, и если я хэш строки, я должен бояться конфликтующих хэшей с разными фотографиями. – BrokenFrog

ответ

1

Сравнение пикселей прекрасно, если изображения не были сохранены или не прошли через формат файла с потерями, например JPEG. Если они не начнут с checksum comparison, и только тогда, если их контрольные суммы не будут делать более обширное сравнение пикселей, хотя алгоритмы с потерями потребуют different approach.

+0

Почему это имеет значение, если оно jpeg, потому что большинство из них jpeg few png – BrokenFrog

+0

Если изображения не были изменены и совпадают, то это не имеет значения. Но если вы сохранили одно и то же изображение в формате JPEG дважды, нет никакой гарантии, что данные в пикселях будут точно такими же. Помните, что JPEG потерян. Если они приходят с вашего телефона, и вы просто копируете их дважды, тогда они будут одинаковыми. –

+0

Вижу, спасибо за помощь, но есть одна вещь, которая не попала мне в голову. С контрольной суммой сравнения вы предлагаете мне создать хэш и проверить их правильно? Если так, то алгоритм был бы следующим: 1-Сравните размер 2-Если совпадение сравнивает контрольную сумму (Итак, если это не соответствует тому, что означает, что изображение отличается), но дело в том, что я даже не потрудился с контрольной суммой, потерял некоторую скорость с но он получил весь контент изображения. Тем не менее, я получил несколько дубликатов. Я думаю, что контрольная сумма не помешает этому. – BrokenFrog