![]() |
|
|
#1
|
|||
|
|||
|
Всем здравствуйте. Сохраняю разные файлы в формат bmp, а затем из bmp вывожу матрицу цветов пикселей. И вот на одном из jpg изображений при попытке получить матрицу (процедура TForm1.Button2Click) выходит сообщение с ошибкой:
--------------------------- Debugger Exception Notification --------------------------- Проект Capcha.exe вызвал исключение класса EAccessViolation с сообщением 'Access violation at address 0048A3A8 in module 'Capcha.exe'. Read of address 01155000'. Процесс остановлен. Используйте Шаг или Запуск для продолжения. --------------------------- OK Help --------------------------- Само изображение трехмерное. Файл во вложении "не вышло". Другие изображения нормально проходят матрицу (например, файл во вложении "вышло"). В чем же дело: в том что изображение трехмерное и надо как-то по-другому с ним работать, или в чём другом? Прошу подсказать, пожалуйста. Вот код (Button1Click-выбор исходного файла, задание имен исходника и bmp файла; Button3Click - сохранение исходника в bmp-файл; Button2Click - получение матрицы цветов пикселей файла bmp - здесь проблемы): Код:
uses
Windows, ..., jpeg, pngimage, GifImage;
.............
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then Image1.Picture.LoadFromFile(OpenDialog1.FileName);
//Image1.Stretch:= true;
Edit4.Text:=OpenDialog1.FileName;
Edit1.Text:=StringReplace(OpenDialog1.FileName,
ExtractFileExt(OpenDialog1.FileName),'',[])+'.bmp';
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Line: pByteArray;
i, j: integer;
s : string;
sl : TStrings;
sl2 : TStrings;
bmp : TBitmap;
begin
sl:= TStringList.Create;
sl2:= TStringList.Create;
bmp:= TBitmap.Create;
bmp.LoadFromFile(Edit1.Text);
for i:= 0 to bmp.Height - 1 do
begin
s:= '';
j:= 0;
Line:= bmp.ScanLine[i];
while j <= bmp.Width * 3 do
begin
s:='R' + IntToStr(Line[j]) +
'G' + IntToStr(Line[j+1]) +
'B' +IntToStr(Line[j+2]);
inc(j, 3);
sl.Add(s);
end;
end;
sl.SaveToFile('D:\Делфи 7 проекты\Матрица капчи.txt');
sl.Free;
Edit2.Text:=IntToStr(bmp.Width+1);
Edit3.Text:=IntToStr(bmp.Height);
sl2.Add(IntToStr(bmp.Width)+ '; ' + IntToStr(bmp.Height));
sl2.SaveToFile('D:\Делфи 7 проекты\Размер капчи.txt');
sl2.Free;
bmp.Free;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
bmp: TBitmap;
begin
bmp:=TBitmap.Create;
with TPicture.Create do begin
LoadFromFile(Edit4.Text); //jpg,png,gif,bmp
bmp.Assign(Graphic);
Free;
end;
bmp.SaveToFile(Edit1.Text);
bmp.Free;
Image2.Picture.LoadFromFile(Edit1.Text);
end;
end. |
|
#2
|
||||
|
||||
|
Вероятно, я стал обыкновенным ретроградом и повёл вас по не правильному пути - пжлст, посмотрите предпоследний пост УК NumLock в этой топке. Извнт, но честно, проверял на *.bmp и *.jpg: оно работало
|
|
#3
|
|||
|
|||
|
DenIvan, ты делаешь предположение, что битмап 24 бита на пиксел, но это не всегда так. Да и весь код какой-то странный, битмап сохраняется, потом загружается и всё это только для того, чтобы сохранить как текст. Приложенные изображения в градациях серого, может стоит писать в текст только одно значение, а не три одинаковых значения РГБ?
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
bmp: TBitmap;
scan: pByteArray;
x,y: integer;
r,g,b,gr: byte;
txt: TStringList;
str: string;
begin
if OpenPictureDialog1.Execute then begin
bmp:=TBitmap.Create;
with TPicture.Create do begin
LoadFromFile(OpenPictureDialog1.FileName);
bmp.Assign(Graphic);
Free;
end;
bmp.PixelFormat:=pf24bit;
txt:=TStringList.Create;
txt.Add('W:'+IntToStr(bmp.Width)+' H:'+IntToStr(bmp.Height));
for y:=0 to bmp.Height-1 do begin
scan:=bmp.ScanLine[y]; str:='';
for x:=0 to bmp.Width-1 do begin
r:=scan[x*3+2]; g:=scan[x*3+1]; b:=scan[x*3+0];
str:=str+'R'+IntToStr(r)+'G'+IntToStr(g)+'B'+IntToStr(b);
//gr:=round(0.299*r+0.587*g+0.114*b);
//str:=str+IntToStr(gr)+'|';
end;
txt.Add(str);
end;
txt.SaveToFile('image.txt');
txt.Free;
bmp.Free;
end;
end; |