Не могу устранить ошибку при использовании TBitmap.ScanLine.
Обрабатываю подряд много изображений, и всё бы хорошо, но где-то раз на пару сотен битмапов получаю ошибку:
Project raised exception class EInvalidGraphicOperation with message 'Scan line index out of range'.
Уже пару раз переписывал функцию чтения...
Вот последний вариант:
type
TByteArr = array[0..9999] of byte;
pByteArr = ^TByteArr;
var
p: pByteArr;
begin
for y:=0 to dy-1 do
begin
p:=bmp.ScanLine[y];
for x:=0 to dx-1 do
begin
b:=p[x*3];
g:=p[x*3+1];
r:=p[x*3+2];
// ...end;
end;
При этом точно известно что битмап bmp валидный, dx и dy — реальные ширина и высота изображения и ширина не превышает 3333 пикселя (9999 / 3).
В общем, все изображения 100% правильные и имеют одинаковый размер, но раз в пятилетку вылазит такая ошибка.
Что это может быть?
Здравствуйте, Bogdan Kobets, Вы писали:
BK>Здравствуйте, altarvic, Вы писали:
A>>может надо
A>> for x:=0 to dx-1 do A>> begin A>> b:=p^[x*3]; A>> g:=p^[x*3+1]; A>> r:=p^[x*3+2]; A>> // ... A>> end;
BK>Наверное надо, но BK>1) работает и без разыменования BK>2) ошибки не устраняет
Судя по ошибке 'Scan line index out of range' видимо у каких-то битмапов в заголовке указана не та ширина/высота, которая на самом деле. А отловить экцепшн и посмотреть на такие битмапы не получается?
Re: ScanLine - out of range
От:
Аноним
Дата:
03.07.06 06:40
Оценка:
BK>Обрабатываю подряд много изображений, и всё бы хорошо, но где-то раз на пару сотен битмапов получаю ошибку: BK>
EInvalidGraphicOperation with message 'Scan line index out of range'.
Есть файл на котором ВСЕГДА выдается эта ошибка ?
Попробуй протрассировать внутрь вызова .ScanLine и выяснить где и почему бросается исключение
Здравствуйте, Аноним, Вы писали:
А>Есть файл на котором ВСЕГДА выдается эта ошибка ?
Он пока ищется...
А>Попробуй протрассировать внутрь вызова .ScanLine и выяснить где и почему бросается исключение
По F7? Не заходит
Здравствуйте, altarvic, Вы писали:
A>Судя по ошибке 'Scan line index out of range' видимо у каких-то битмапов в заголовке указана не та ширина/высота, которая на самом деле.
Не думаю. Я создаю битмап только один раз, а потом только рисую на нем. Размеры не меняю.
A>А отловить экцепшн и посмотреть на такие битмапы не получается?
Нет — вываливается до блока except ... end
begin
for y:=0 to dy-1 do
begin
p:=bmp.ScanLine[y];
for x:=0 to dx-1 do
А с битмапом точно никто ничего не делает между
dy := bmp.Height
и
p:=bmp.ScanLine[y]?
Может какие другие процессы этой картинкой пользуют или ещё чего?
Может ты где-нибудь память затираешь в процессе обработки картинки?
Никаких других исключений не выскакивает?
Здравствуйте, Dimonka, Вы писали:
D>А с битмапом точно никто ничего не делает между D>dy := bmp.Height D>и D>p:=bmp.ScanLine[y]?
Нет, dx и dy определяются непосредственно перед ScanLine;
D>Может какие другие процессы этой картинкой пользуют или ещё чего?
Хм... Ведь TTimer не создает нового потока?
procedure TForm1.Timer1Timer(Sender: TObject);
begin// возможный ресайзif bmp.Width <> dx then bmp.Width:=dx;
if bmp.Height <> dy then bmp.Height:=dy;
// рисование на bmp
BitBlt(bmp.Canvas.Handle, 0, 0, dx, dy, SomeHandle, 0, 0, SRCCopy);
// вызов процедуры для обработки bmp
SomeProc(bmp);
end;
procedure SomeProc(bmp: TBitmap); // здесь могут быть какие-то проблемы с указателем?var
dx, dy: word;
begin
dx:=bmp.Width;
dy:=bmp.Height;
for y:=0 to dy-1 do
begin// где-то здесь - исключение
p:=bmp.ScanLine[y];
...
end;
Ведь, пока не отработает SomeProc, новое событие OnTimer не наступит?
D>Может ты где-нибудь память затираешь в процессе обработки картинки?
Память, где расположена bmp?
Меня только смущает, обработка чего идет в SomeProc — того же битмапа (указателя), что и в процедуре Timer1Timer или копии?
D>Никаких других исключений не выскакивает?
Нет.
Здравствуйте, Bogdan Kobets, Вы писали:
BK>Ведь, пока не отработает SomeProc, новое событие OnTimer не наступит?
Ещё как наступит!
Если интервал истёк, а обработчик не завершился, то будет по новой в него заходить. Чтобы этого избежать – выключать таймер при входе в обработчик и включать при выходе.
Re[4]: ScanLine - out of range
От:
Аноним
Дата:
04.10.06 13:52
Оценка:
Здравствуйте, BAHbKA, Вы писали:
BAH>Ещё как наступит!
а у меня точно такая же ситуация (тоже исключение) что и у Bogdan Kobets, но у меня точно никакой другой процесс картинкой не пользуется. Сравнивается 2 изображения. Не могу отловить когда выползает эксцепшен хоть ты тресни