Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.05.2012, 00:20   #41
FoggySpurs
Пользователь
 
Регистрация: 14.04.2012
Сообщений: 41
По умолчанию

Цитата:
Сообщение от s-andriano Посмотреть сообщение
Кто сказал "всю строку"?
Просто вместо 1995 чтений по 1 байту нужно сразу читать фрагмент файла длиной 1995 байт.
Т.е. "всю строку", но не исходного изображения, а требуемого фрагмента.
и как это будет выглядеть? я про код.
FoggySpurs вне форума Ответить с цитированием
Старый 27.05.2012, 00:31   #42
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Код:
var
f:TMemoryStream;
r,g,b:byte;
w,h:integer;
temp:byte;
i:integer;
begin
f:=TMemoryStream.Create;
f.LoadfromFile('1.bmp');
// переходим на начало байт, где хранится ширина картинки
f.Seek(18,soBeginning);
// считываем по байту чтобы узнать ширину
f.Read(temp,1);
w:=temp;
f.Read(temp,1);
w:=temp shl 8 +w;
f.Read(temp,1);
w:=temp shl 16 +w;
f.Read(temp,1);
w:=temp shl 24 +w;
// теперь знаем ширину изображения. она в переменной w
// считываем по байту чтобы узнать высоту
f.Read(temp,1);
h:=temp;
f.Read(temp,1);
h:=temp shl 8 +h;
f.Read(temp,1);
h:=temp shl 16 +h;
f.Read(temp,1);
h:=temp shl 24 +h;
// теперь знаем высоту изображения. она в переменной h

f.seek(w*3+1,soEnd);// переходим на байт, с которого начинается первая строка изображения в вашем файле

// цикл считает всю строку изображения и нарисует в PaintBox, при условии, что 
//ширина изображения и ширина PaintBox одинаковы. Но это не ваш случай.
// Доделать вам осталось копейки.
for i:=0 to w-1 do
begin
  f.Read(b,1);
  f.Read(g,1);
  f.Read(r,1);
  PaintBox1.Canvas.Pixels[i,0]:=RGB(r,g,b);
end;
f.Free;
end;
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 27.05.2012 в 04:54.
Rin вне форума Ответить с цитированием
Старый 27.05.2012, 00:40   #43
FoggySpurs
Пользователь
 
Регистрация: 14.04.2012
Сообщений: 41
По умолчанию

что за ф с долларами? зачем выяснять длинну и ширину если их можно взять из шапки!? переходим на байт, с которого начинается первая сторка--- первая строка где в файле 1-я или и изображении??
FoggySpurs вне форума Ответить с цитированием
Старый 27.05.2012, 04:57   #44
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Цитата:
зачем выяснять длинну и ширину если их можно взять из шапки!?
Объясните каким образом вы будете брать длину и ширину.

На счет TMemoryStream.
Как посоветовал Аватар, и я с ним соглашаюсь - нужно использовать TFileStream, т.к. файл не загружается в оперативную память. При использовании же TBitmap и TMemoryStream файл загружается в оперативку.
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 27.05.2012 в 05:02.
Rin вне форума Ответить с цитированием
Старый 27.05.2012, 09:42   #45
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

[QUOTE=Rin;1051229]А кто-нибудь может мне объяснить, зачем вот это:
Код:
f:=TMemoryStream.Create;
f.LoadfromFile('1.bmp');
// переходим на начало байт, где хранится ширина картинки
f.Seek(18,soBeginning);
// считываем по байту чтобы узнать ширину
f.Read(temp,1);
w:=temp;
f.Read(temp,1);
w:=temp shl 8 +w;
f.Read(temp,1);
w:=temp shl 16 +w;
f.Read(temp,1);
w:=temp shl 24 +w;
// теперь знаем ширину изображения. она в переменной w
// считываем по байту чтобы узнать высоту
f.Read(temp,1);
h:=temp;
f.Read(temp,1);
h:=temp shl 8 +h;
f.Read(temp,1);
h:=temp shl 16 +h;
f.Read(temp,1);
h:=temp shl 24 +h;
Вместо гораздо более простого:
Код:
assignfile(f, '1.bmp');
reset(f,1);
seek(f, 14);
blockread(f, BMP_header, sizeof(BMP_header));
Тем более, что приведенный первым код читает только ширину и высоту изображения, а для того, чтобы программа надежно работала этого далеко не достаточно - нужно еще считать, минимум, глубину цвета, чтобы убедиться, что она именно 24 бита, тип компрессии, чтобы убедиться, что изображение не сжато и смещение блока данных, т.к. встречаются файлы с 24 bpp и палитрой.

Да и вместо
Код:
for i:=0 to w-1 do
begin
  f.Read(b,1);
  f.Read(g,1);
  f.Read(r,1);
проще и быстрее будет
Код:
blockread(f, buffer, w*3);
s-andriano вне форума Ответить с цитированием
Старый 27.05.2012, 10:09   #46
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

По поводу кода в #42. Для FileStream (и других Stream) вместо по-байтного чтения можно (и нужно) пользоваться чтением в буфер. Например для чтения DWORD (при этом нет необходимости кучу сдвигов делать)
Код:
var biWidth: DWORD;
...
FS.ReadBuffer(biWidth,4);
Цепочку байтов этим же методом в массив байтов
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 27.05.2012 в 10:20.
Аватар вне форума Ответить с цитированием
Старый 28.05.2012, 06:08   #47
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Цитата:
По поводу кода в #42. Для FileStream (и других Stream) вместо по-байтного чтения можно (и нужно) пользоваться чтением в буфер. Например для чтения DWORD (при этом нет необходимости кучу сдвигов делать)
Код:
var biWidth: DWORD;
...
FS.ReadBuffer(biWidth,4);
Не припомню, что за графический формат изучал, но при считывании нескольких байтов я получал не то, что на самом деле. Поэтому и считывал побайтно.
Цитата:
Цепочку байтов этим же методом в массив байтов
В BMP вместо RGB все хранится в BGR, поэтому придется ещё swap'ать при таком подходе.
Цитата:
Тем более, что приведенный первым код читает только ширину и высоту изображения, а для того, чтобы программа надежно работала этого далеко не достаточно - нужно еще считать, минимум, глубину цвета, чтобы убедиться, что она именно 24 бита, тип компрессии, чтобы убедиться, что изображение не сжато и смещение блока данных, т.к. встречаются файлы с 24 bpp и палитрой.
На счет глубины цвета Вы сами сказали, что у ТС 24 бита на пиксель.
Согласно Вики, при 24-битном формате пикселя компрессии нет, и палитры быть не должно.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 28.05.2012, 13:35   #48
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Цитата:
Сообщение от Rin Посмотреть сообщение
Не припомню, что за графический формат изучал, но при считывании нескольких байтов я получал не то, что на самом деле. Поэтому и считывал побайтно.
Ну на основе одной программы с ошибками вряд ли можно делать вывод о работоспособности системной функции.
Цитата:
В BMP вместо RGB все хранится в BGR, поэтому придется ещё swap'ать при таком подходе.
Во-первых, вместо какого формата мы не знаем - в видеокарте может встретиться самый экзотический порядок цветов. Так что не исключено, драйверам придется переставлять байты обратно.
Поэтому лично я, работая в BMP, предпочитаю отдать данные системе тоже в формате BMP, чтобы уже она думала, нужно ли что-то куда-то перекодировать, и как именно.
Кстати, видеокарта перекодирует цвет аппаратно, не используя ресурс ЦП, так что с точки зрения программы это вообще не занимает времени.
Но в любом случае - перестановка байтов в ОП - операция существенно более быстрая, чем обмен данными с диском.
Цитата:
На счет глубины цвета Вы сами сказали, что у ТС 24 бита на пиксель.
Согласно Вики, при 24-битном формате пикселя компрессии нет, и палитры быть не должно.
Я это предположил.
Но в любом случае - правильная программа должна корректно работать всегда, даже с некорректными данными. Поэтому и нужны дополнительные проверки.
Согласитесь, гораздо лучше, если программа будет выводит мессаджбокс с фразой "Программа поддержтвает только изображения True Color (24 bpp)", чем если будет вылетать по неясной ошибке при попытке открытия файла.

И еще: "палитры быть не должно" и "палитры нет" - разные вещи.

Последний раз редактировалось s-andriano; 28.05.2012 в 13:40.
s-andriano вне форума Ответить с цитированием
Старый 28.05.2012, 14:36   #49
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Вспомнил, в формате JPG длина APPn имеет 2 байта, и имеет обратный порядок байт. Считывая длину APP, не мог понять откуда берутся такие огромные цифры.

Можно перейти на 29 байт, считать его, и тем самым узнать какая глубина цвета.

На кой в 24bbp хранить палитру, ведь на каждую компоненту цвета приходится ровно 1 байт, следовательно компрессии делать не надо. Отсюда вывод, что палитры в True Color нет.

Смещение, от которого начинается изображение нам и не нужно, т.к. мы будет
считывать с конца файла, и чтобы перейти на первый байт изображения нужно
будет написать f.seek(w*h*3,soEnd).

На счет swap'a байт в ОП и считывания байт с харда я согласен. Про работу проги при некорректных данных тоже согласен.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 28.05.2012, 19:14   #50
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Цитата:
Сообщение от Rin Посмотреть сообщение
Вспомнил, в формате JPG длина APPn имеет 2 байта, и имеет обратный порядок байт. Считывая длину APP, не мог понять откуда берутся такие огромные цифры.
Конкретно JPEG не ковырял, но вообще порядок отличный от Little-Endian встречается в различных форматах файлов не так уж редко.
Intel - не единственная архитектура, и некоторые форматы файлов первоначально разрабатывались не для нее.
Бывают и более сложные случаи, когда часть полей имеет один порядок байтов, а часть - другой.
Цитата:
На кой в 24bbp хранить палитру, ведь на каждую компоненту цвета приходится ровно 1 байт, следовательно компрессии делать не надо. Отсюда вывод, что палитры в True Color нет.
Вывод неверный.
Верный вывод: "она там не нужна".
Но формату наличие палитры в таких файлах не противоречит, и на практике такие файлы встречаются.
Цитата:
Смещение, от которого начинается изображение нам и не нужно, т.к. мы будет
считывать с конца файла
Это неоптимальный вариант. Гораздо быстрее будет читать, начиная с начала.
s-andriano вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Открыть файл, разделить ячейку на 1000, сохранить файл, закрыть файл. Как? Ник Харди Microsoft Office Excel 7 30.01.2012 18:47
Не заливается на ФТП большой файл ramzes777 Работа с сетью в Delphi 3 26.10.2011 10:19
Разбить большой файл на более мелкие Sat_Kelman Microsoft Office Excel 4 18.03.2011 13:06
отдавать большой файл с фтп TaTT DoGG PHP 5 03.07.2009 10:34
ActiveX не хочет читать большой файл Miklek Общие вопросы Delphi 0 02.04.2009 11:55