Форум программистов, компьютерный форум, киберфорум
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 03.07.2024
Сообщений: 6
1
Delphi 6-7

Отрисовка Jpeg в Битмапе

03.07.2024, 11:54. Показов 540. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
всем доброго времени суток. назрел один вопрос не могу никак решить.
есть набор жыпегов около 150 тысяч нужно среди них вычленить дубликаты
делаю это так сканирую каталоги, имена картинок сливаю в текстовый файл затем этот файл загружаю в стринглист.
начинаю перебирать эти файлики:
открываю джипегимиджем картинку,
отрисовываю ее стретчдравом на BMP 100х100 пикселов
формирую по этой BMP-шке некую хешсумму
и сливаю ее в файл в формате имя файла картинки,хеш сумма
все просто как трусы

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type
thash=array[0..99] of trgb;
pitem=^titem;
  titem=object
     name:pshortstring;
    hash:thash;
    
    constructor init;
    procedure loadfromfile(var f:file);
    procedure savetofile(var f:file);
    function getrgb(i:integer):string;
 
 
    procedure showhash(cnv:tcanvas;x,y:integer);
    destructor destroy;
    procedure find(ls:tstringlist);
    procedure setname(s:shortstring);
  end;
вот собственно проблемный код

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
bb:=tbitmap.Create;
bb.Width:=100;
bb.height:=100;
for i:=0 to ls.Count-1 do begin
s:=ls[i];if s='' then continue;
 
inc(j);
if th.count=10 then th.push_to_disk('c:\temp\listfiles.hash');
pic:=nil;
if pos('.JPG',s)=length(s)-3 then pic:=tjpegimage.create;
if pos('.JPEG',s)=length(s)-4 then pic:=tjpegimage.create;
if pos('.BMP',s)=length(s)-3 then pic:=tbitmap.create;
if pic=nil then continue;
pp:=new(pitem,init);
pp^.setname(s);
 
pic.LoadFromFile(s); //вот здесь загружаю жыпег
bb.canvas.stretchdraw(rect(0,0,100,100),pic); //здесь отрисовываю и вот здесь программа на некоторых файлах вылетает именно в этой строчке, проверено трассировкой
pic.Free;
hashpic(bb,pp^.hash); //тут формирую хешсумму
th.additems(pp);
 
stb.Panels[0].Text:=inttostr(i)+':'+inttostr(j);
stb.repaint;
end;
проблема вот в чем
при отрисовке некоторых жипегов стречдравом программа вылетает
я не могу понять почему, эта картинка прекрасно открывается в любом вюере, ну там фарстоне или любым другим.
причем я проделал такой опыт: открыл этот файл в гимпе, налисовал на нем точку в один пиксел в уголочке и заново сохранил.
И, о Чудо!, моя программулька его проглотила, но сами понимаете, это не решение проблемы, поскольку порядковый номер эток картинки был после 30 000
какие пути решения вижу я
1. найти более новую версию TJpegImage которая понимает все разновидности жыпегов, но где его найти для 7-й дельфы я не знаю
2 чтобы просто пропускала такой файл

Delphi
1
2
3
4
5
6
pic.LoadFromFile(s); 
try
bb.canvas.stretchdraw(rect(0,0,100,100),pic); 
finally
bb.canvas.rectangle(0,0,100,100); 
end;
но такая конструкция приводит к завершению программы вне зависимости от того где я ее запускаю из-под делфы или из винды(вопрос из оффтопика try except не помог)

может посоветуете что умное?.
я просто ООООЧЕНЬ давно не кодил, некоторые навыки подрастерял
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.07.2024, 11:54
Ответы с готовыми решениями:

Как заменить цвет в битмапе
Всем здравствуйте. В Image1 загружена картинка bmp. В ней присутствует, например, чёрный цвет....

Resize JPEG, BMP, GIF, PNG --> JPEG
Доброго дня! Стала задача сделать ресайзер. Требования: картинка по соотношению вес/качество...

Построение дерева на битмапе
Страхова компанія Бухгалтерія-------------Страхова компанія...

Как нарисовать эллипс на битмапе?
Как нарисовать елипс на битмапе? У меня рисует только при нажатии на кнопку и то под битмапом........

Как нарисовать на одном битмапе другой
Есть код: Image im = new Bitmap(pictureBox1.Image.Width, pictureBox1.Image.Height + 30); ...

14
Модератор
3748 / 2248 / 782
Регистрация: 15.11.2015
Сообщений: 8,956
03.07.2024, 12:18 2
Цитата Сообщение от Dinulya Посмотреть сообщение
при отрисовке некоторых жипегов стречдравом программа вылетает
Нужно убедиться, что это действительно JPEG, а не что-то иное с расширением .jpg. Можно открыть в том же блокноте и посмотреть на первые символы. У JPEG будет "яШ" (обычно видно "яШяа") и возможно, чуть дальше будет "JFIF".

Цитата Сообщение от Dinulya Посмотреть сообщение
поскольку порядковый номер эток картинки был после 30 000
Можно загрузку и декодирование поместить в блок
Delphi
1
2
3
4
5
try
...
except
...
end;
и тут уже решить, что с ней делать, записать в лог, который файл не получилось декодировать, или игнорировать ошибку.

Добавлено через 2 минуты
Цитата Сообщение от Dinulya Посмотреть сообщение
но такая конструкция приводит к завершению программы вне зависимости от того где я ее запускаю из-под делфы
Странно. Сам файл, который не получается загрузить, можно сюда прикрепить? Его нужно поместить в архив, чтобы движок форума не внёс в файл изменения.

Добавлено через 7 минут
Цитата Сообщение от Dinulya Посмотреть сообщение
есть набор жыпегов около 150 тысяч нужно среди них вычленить дубликаты
Для этого есть готовая замечательная программа "SearchMyFiles", ищет очень быстро и без хэшей. Полностью читает только одинаковые файлы.
1
0 / 0 / 0
Регистрация: 03.07.2024
Сообщений: 6
03.07.2024, 12:37  [ТС] 3
Цитата Сообщение от AzAtom Посмотреть сообщение
Нужно убедиться, что это действительно JPEG, а не что-то иное с расширением .jpg. Можно открыть в том же блокноте и посмотреть на первые символы. У JPEG будет "яШ" (обычно видно "яШяа") и возможно, чуть дальше будет "JFIF".
нет это был действительно жыпег, я проверял
Цитата Сообщение от AzAtom Посмотреть сообщение
Странно. Сам файл, который не получается загрузить, можно сюда прикрепить? Его нужно поместить в архив, чтобы движок форума не внёс в файл изменения.
как я писал выше его прогнал через Gimp и программа его проглотила и это не решение проблемы. поскольку его прекрасно читает и отображает FarStone и узнавать о новых "битых" картинках по вылету программы как-бы не есть гуд.
0
Модератор
3748 / 2248 / 782
Регистрация: 15.11.2015
Сообщений: 8,956
03.07.2024, 12:41 4
Цитата Сообщение от Dinulya Посмотреть сообщение
открываю джипегимиджем картинку,
отрисовываю ее стретчдравом на BMP 100х100 пикселов
формирую по этой BMP-шке некую хешсумму
и сливаю ее в файл в формате имя файла картинки,хеш сумма
А зачем декодировать и смотреть хэш? Можно же взять хэш самого исходного файла.

Ну и, программы готовые есть для поиска дублей.
1
0 / 0 / 0
Регистрация: 03.07.2024
Сообщений: 6
03.07.2024, 12:46  [ТС] 5
Цитата Сообщение от AzAtom Посмотреть сообщение
Для этого есть готовая замечательная программа "SearchMyFiles", ищет очень быстро и без хэшей. Полностью читает только одинаковые файлы.
мне нужно не по размеру/имени искать, а по самой картинке, если картинки с одним содержанием но разные по размеру они все равно должны попадать в "дубликаты"
0
Модератор
3748 / 2248 / 782
Регистрация: 15.11.2015
Сообщений: 8,956
03.07.2024, 12:57 6
Цитата Сообщение от Dinulya Посмотреть сообщение
если картинки с одним содержанием но разные по размеру они все равно должны попадать в "дубликаты"
Тогда, хэш однозначно не подойдет. Нужно попиксельно сравнивать с учётом некоторой возможной разницы.

Я уменьшал размер до 64х48 и уже на таком изображении находил разницу между каждым компонентом цвета (R, G, B) каждого пикселя и выводил процент отличия по всей картинке. Затем, просто сравнивал с заданным мной процентом допустимого отличия и если отличие мало, то оба файла добавляются в список.
1
0 / 0 / 0
Регистрация: 03.07.2024
Сообщений: 6
03.07.2024, 14:06  [ТС] 7
Цитата Сообщение от AzAtom Посмотреть сообщение
А зачем декодировать и смотреть хэш? Можно же взять хэш самого исходного файла.
Ну и, программы готовые есть для поиска дублей.
а как проверить картинки на совпадение?
я разбиваю битмат 100х100 на 10 квадратиков 10х10 пикселей усредняю значение их цветов и помещаю в массив hash,
а затем сравниваю массивы от разных картинок и определенной точностью.
может быть есть какие другие алгоритмы сравнения картинок, я не знаю, как я писал я очень долго не кодил.

Добавлено через 29 минут
Цитата Сообщение от AzAtom Посмотреть сообщение
Я уменьшал размер до 64х48 и уже на таком изображении находил разницу между каждым компонентом цвета (R, G, B) каждого пикселя и выводил процент отличия по всей картинке. Затем, просто сравнивал с заданным мной процентом допустимого отличия и если отличие мало, то оба файла добавляются в список.
это все голимая математика и с ней проблем нету.
мне нужно либо игнорировать такие файлы БЕЗ аварийного завершения программы,
либо более продвинутый TJpegImage который читает все версии жыпегов,
либо разобраться почему не отрисовывается, уже корректно прочитанный в .loadfromfile, жыпег.
0
Модератор
3748 / 2248 / 782
Регистрация: 15.11.2015
Сообщений: 8,956
03.07.2024, 14:17 8
Цитата Сообщение от Dinulya Посмотреть сообщение
либо разобраться почему не отрисовывается,
Корректные JPEG у меня всегда открывались. Нужен сам файл, чтобы проверить, в чём дело. Файла не предоставлено.
0
0 / 0 / 0
Регистрация: 03.07.2024
Сообщений: 6
03.07.2024, 14:42  [ТС] 9
Цитата Сообщение от AzAtom Посмотреть сообщение
Файла не предоставлено.
вечером выложу
0
5860 / 4588 / 1448
Регистрация: 14.04.2014
Сообщений: 20,352
Записей в блоге: 20
03.07.2024, 16:05 10
try except решит проблему с сожалением про 30000
а битый файл это отдельная проблема, которую можно решать вплоть до ручной обработки
0
3759 / 2263 / 705
Регистрация: 29.05.2013
Сообщений: 9,613
03.07.2024, 16:35 11
Существуют уже готовые решения для таких задач. Популярный файловый менеджер Total commander уже давно умеет такое делать. Есть и более специализированные программы для поиска дубликатов картинок, например ImageDupeless имеет гибкие настройки схожести при поиске похожих картинок.
0
523 / 226 / 23
Регистрация: 05.05.2022
Сообщений: 1,483
03.07.2024, 18:57 12
Главная особенность хэша, что минимальное изменение исходных данных должно радикально менять результат работы хэш-функции.

В принципе, ImageDupless и т. п. для разовой работы, но какие алгоритмы используют они это тоже вопрос. И насколько я помню, у меня эти проги работали далеко не идеально. На самом деле, довольно плохо работает и поиск по картинке у Гугла, особенно, если картинка в градациях серого.
0
0 / 0 / 0
Регистрация: 03.07.2024
Сообщений: 6
04.07.2024, 08:52  [ТС] 13
утречко всем
моя программулька засосала в себя все файлы, 143 тысячи, среди них оказалось около 10 файлов непонятной версии жыпега, ну как непонятной, их tjpegimage в D7 не читал, хотя стандартные средства вин10,paint, faststone читали и показывали легко, причем, если я их открываю в паинте, ставлю куда-нибудь контрастную точку и сохраняю, то паинт говорит что прозрачность в жыпеге не поддерживается. о как! в этих файликах был прозрачный слой!!!! после чего сохраняет в нормальный жыпег и tjpegimage его нормально проглатывает.
в общем всем отозвавшимся спасибо!
единственная просьба, поскольку количество файлов будет увеличиваться, и соответственно на отлов эти "битых" жыпегов будет уходить все больше времени, может у кого есть ссылочка на более продвинутый tjpegimage для D7, поделитесь если не жалко!
а спецом зарегался на torry.net но там либо за бабки, либо в бесплатном архиве не хватает некоторых файлов
0
3759 / 2263 / 705
Регистрация: 29.05.2013
Сообщений: 9,613
04.07.2024, 13:05 14
Цитата Сообщение от Dinulya Посмотреть сообщение
единственная просьба, поскольку количество файлов будет увеличиваться, и соответственно на отлов эти "битых" жыпегов будет уходить все больше времени, может у кого есть ссылочка на более продвинутый tjpegimage для D7, поделитесь если не жалко!
а спецом зарегался на torry.net но там либо за бабки, либо в бесплатном архиве не хватает некоторых файлов
Попробуйте найти библиотеку компонент ImageEn для Delphi. Это одна из лучших библиотек работы с фото/видео поддерживающая большинство популярных форматов. Отличается высокой скоростью работы и большим набором инструментов обработки фото.
0
3455 / 1643 / 236
Регистрация: 26.02.2009
Сообщений: 8,034
Записей в блоге: 5
09.07.2024, 12:16 15
Цитата Сообщение от Dinulya Посмотреть сообщение
около 10 файлов непонятной версии жыпега
скинь их сюда уже наконец в архиве
0
09.07.2024, 12:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.07.2024, 12:16
Помогаю со студенческими работами здесь

Как определить есть ли изображение в битмапе?
Собственно как поставить условие, что бы проверить если ли изображение в битмапе?

Поиск нескольких пикселей определённого цвета в битмапе
Здравствуйте. Программа ищет пиксели определённого цвета в битмапе. 1. Можно ли упростить как...

Как найти изображение в битмапе и узнать её координаты?
День всем добрый! Допустим, у меня есть битмап. Как мне найти в нём нужное мне изображение?...

Как отображать буквы из TTF шрифта в битмапе со сглаживанием (или без)
У меня задача - нужно отображать буквы из TTF-шрифта на экране без использования каких-либо средств...

JPEG->MemoryStream = 120тиков а JPEG->Image1 и Image1->MemoryStream = 30тиков?
Добрый вечер. Впринципе название темы все объясняет. Ради любопытства думал что может по умолчанию...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru