12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
|
1 | |
Как из файла JPEG вытащить размер изображения в пикселях?07.11.2014, 12:43. Показов 5113. Ответов 18
Метки нет (Все метки)
Пишу на С курсовую "Работа с бинарными файлами" ( Пишу в тему по С++) потому в "Сс для начинающих ответа не будет точно" уж извините Админы, требуется алгоритм поэтому просто не знаю уже куда и написать.
Прочел EXIF спецификацию, понял что да есть много битов с разными значениями разных типов и тд. Начал с простого нашел биты по которым хранится строковые данные, от файла к файлу тото читается что то нет (Модель камеры и прочее) понял что все очень специфично для каждого производителя ну да ладно, напишу в виде учебного задания про Apple и Canon. НО никак немого вычитать разрешение W H. Изучил efix.c и jhead.h - мощные функции описаны, структуры для всего EXIF, я понимаю что истина в этих файлов но пока не хватает знаний разобраться куча #define и передача параметров в функции , не могу проследить интересующий меня момент. Прочел про золовок JPEG и нашел откуда вычитать соотношение сторон, в чем разрешение в дюймах или сантиметрах, разрешение на дюйм (72, 96 и тд) НО никак не пойму откуда берется или как высчитывается банальные размеры W x H (1920 * 1080 к примеру). Забил на EXIF создал тупо в PAINTE белый квадратный холст 200 на 200 сохранил как JPEG, открываю Hex редактором все заголовок есть 96 pix/inc есть, но где (200 на 200) ГДЕ искать или Как оно вычисляется? Сижу неделю.. Прошу помощи.. Администрация еще раз извиняюсь есть не в ту тему написал, перенесите куда следует лишь бы был толк.
0
|
07.11.2014, 12:43 | |
Ответы с готовыми решениями:
18
Как зафиксировать размер изображения в пикселях Размер изображения в см. если дан размер в пикселях Как вытащить размер изображения при загрузки через OpenFileDialog? Как узнать размер строки в пикселях? |
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
|
07.11.2014, 14:33 | 2 |
Размеры в хранятся в секциях SOF (Y и X).
1
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
|
07.11.2014, 17:07 [ТС] | 3 |
1) Правильно ли я понимаю что у блоков нет фиксированного адреса в файле и искать его нужно по всему файлу в данном случае сочетание (FF C0), ок допустим написали поиск дошли до маркера.
2) Отступаем длину последовательно идущих данных от начала маркера до интересующих нас значений? (поправьте меня пожалуйста если я никак отсчитываю) FF C0 - Marker 00 11 - Frame Header 08 - Sample Precision 0A 20 - Y , 07 90 - X? переводим целиком из hex в dec = 2592 * 1936 И все черт возьми получаеться!) Тогда остается самый главный вопрос маркеры строго адресованные в файле или надо устраивать программный поиск?
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
||||||
07.11.2014, 21:08 | 4 | |||||
Сообщение было отмечено tezaurismosis как решение
Решение
Фиксированной структуры нет, файл состоит из секций, длина которых может быть различной. Маркеры секций надо не искать по всему файлу, а перемещаться последовательно от начальной секции, пока не дойдёшь до интересующей. Большинство секций после маркера содержат длину. Вот я на скорую руку сделал:
Здесь только три типа SOF учтено. Вообще их больше.
0
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
|
07.11.2014, 21:15 [ТС] | 5 |
nmcf, Супер спасибо, если не трудно буду расспрашивать по твоему листингу ( потому как официально прогу свою должен написать на Си)
Почему ты ищешь маркеры 0xC1FF а не FFC1? я наверно не знаю каких то совсем основ( остальное пока вроде бы понятно ..
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
|
07.11.2014, 21:19 | 6 |
Потому что в памяти байты хранятся от младших к старшим в порядке возрастания адреса, а в файле почему-то наоборот. Я реализовал чтение каждого из двух байтов раздельно. Ты можешь по-другому придумать.
1
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
|
07.11.2014, 21:31 [ТС] | 7 |
nmcf, вот в моем тупом случае считываю в 2 переменных char 0A и 20
как мне из этого потом сложить число 0A 20 (hex) = 2592 (dec)
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
|
07.11.2014, 21:48 | 8 |
Сдвигом, например, (0A << 8) + 20
Только char - тип со знаком, поэтому если арифметически соединять, могут быть сложности при больших величинах. Лучше сделай как у меня через unsigned short int и указатели.
0
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
|
07.11.2014, 22:02 [ТС] | 9 |
ifs.ignore(2 + 1); не могу найти аналог на си
ifs.read((char *)&pic_height + 1, 1); и тут понимаю что чтение из файла в переменную pic_height (типа unsinget char а вот что такое +1 и ,1) непонимаю
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
|
07.11.2014, 22:11 | 10 |
Зачем тебе этот древний Си? Где ты его вообще откопал? ftell() и fseek() попробуй.
Вот это достаточно древняя конструкция: (char *)&pic_height - интерпретировать unsigned short как массив из двух байтов. У нулевого будет адрес (char *)&pic_height, у первого (char *)&pic_height + 1. Арифметика указателей.
0
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
||||||
08.11.2014, 02:31 [ТС] | 11 | |||||
nmcf, Си в учебных целях для понимания основ... учусь на курсах, пройду си потом будет с++ там будут потоки и тд будет попроще.
Написал вот так, громоздко глупо но пока хоть так, у тебя возьму алгоритм поиска маркеров, еще раз тебе спасибо!
nmcf, Все получилось вынул разрешение, проверил на нескольких файлах, хотел спросить то что ты в первый самый пост отправил это что за мануал? я из твоей картинки там я понял больше чем за часа в google...
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
|||||||||||
08.11.2014, 10:40 | 12 | ||||||||||
По твоему коду замечания. Нельзя в целочисленной арифметике использовать double, он не гарантирует точность представления, используй long. Далее, двухбайтные длины секций беззнаковые, судя по всему, поэтому хранить в беззнаковой переменной надо, а у тебя int. Сдвиг, как я сказал, из-за этих знаков может некорректный результат дать для секций большой длины. Не понимаешь указатели, используй, например union, он есть в Си:
Добавлено через 20 минут Можно сразу читать по 2 байта, и менять местами:
0
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
||||||
08.11.2014, 12:36 [ТС] | 13 | |||||
Тут так не проходит наверно из за собственностей древнего fread
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
||||||
08.11.2014, 13:03 | 14 | |||||
fread() принимает указатель. У тебя же в прошлом фрагменте это учтено. И нумерация 1, 0.
0
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
|
08.11.2014, 13:08 [ТС] | 15 |
второй скрин сообщает нам что и & не прокатывает, я пробовал еще в первый раз
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
|||||||||||
08.11.2014, 13:12 | 16 | ||||||||||
Как тогда это у тебя работало?
0
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
||||||
08.11.2014, 14:16 [ТС] | 17 | |||||
нет скобки ожидаемо не помогли, тут дело скорее в том кто под чем пишет и компилирует, вот у меня Дельфийское Чудовище для обучающийся " DevC++ 5.8.1 с компилятором (TDM-GCC 4.8.1 64-bit Debug) " Win 7 HP 64.
А ты под чем пишешь?
0
|
7796 / 6562 / 2985
Регистрация: 14.04.2014
Сообщений: 28,699
|
|
08.11.2014, 18:07 | 18 |
Это же стандартные вещи, а не какие-то специфические библиотеки. Должно работать. И что, в этом DevC++ тип int двухбайтный?
У меня Visual C++.
0
|
12 / 11 / 6
Регистрация: 05.10.2013
Сообщений: 219
|
|
08.11.2014, 20:19 [ТС] | 19 |
nmcf,
unsigned int 2 (16) от 0 до 65535
0
|
08.11.2014, 20:19 | |
08.11.2014, 20:19 | |
Помогаю со студенческими работами здесь
19
Как узнать размеры изображения в пикселях (N x N) не загружая его в память Как узнать размеры изображения в пикселях (высоту и ширину) до его загрузки в TImage как восстановить поврежденные jpeg изображения? Как сделать размер jpeg равный размеру timage Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |