-
Нужно BMP-изображение загнать в массив для дальнейшей работы с ним
получился вот такой код, только никак не могу найти ошибку, подскажите
[CODE]unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
CONST
PixelCountMax = 32768;
TYPE
pRGBArray = ^TRGBArray;
TRGBArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
OriginalBitmap:TBitmap;
ProcessedBitmap:TBitmap;
i,j:integer;
RowOriginal:pRGBArray;
RowProcessed:pRGBArray;
implementation
{$R *.dfm}
procedure CreateBMP;
begin
if OriginalBitmap.PixelFormat <> pf24bit then
begin
ShowMessage('Изображение должно быть 24-х битным');
Exit;
end;
for j:=OriginalBitmap.Height-1 downto 0 do
begin
RowOriginal:=pRGBArray(OriginalBitmap.Scanline[j]);
RowProcessed:=pRGBArray(ProcessedBitmap.Scanline[j]);
for i:=OriginalBitmap.Width-1 downto 0 do
begin
RowProcessed[i].rgbtRed:=RowOriginal[i].rgbtRed;
RowProcessed[i].rgbtGreen:=RowOriginal[i].rgbtGreen;
RowProcessed[i].rgbtBlue:=RowOriginal[i].rgbtBlue;
end;
end;
Form1.Canvas.Pixels[i,j]:=(RowProcessed[i].rgbtRed shl 16)+
(RowProcessed[i].rgbtGreen shl 8) +
RowProcessed[i].rgbtBlue;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
OriginalBitmap.LoadFromFile('0003.bmp');
ProcessedBitmap.width:=800;
ProcessedBitmap.height:=600;
createbmp;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OriginalBitmap:=TBitmap.Create;
ProcessedBitmap:=TBitmap.Create;
end;[/CODE]
По нажатию на кнопку ничего не происходит и выдает
Process is not accessible
Thread Exit: Thread ID: 3852. Process Project1.exe (3536)
вот юнит с BMP - изображением
http://www.megaupload.com/?d=XX55QNQD -
Rouse_ © (16.09.10 20:30) [1]
> только никак не могу найти ошибку, подскажите
Ворнинги читать потомучто ленишся:
[DCC Warning] Unit1.pas(47): W1019 For loop control variable must be simple local variable
[DCC Warning] Unit1.pas(52): W1019 For loop control variable must be simple local variable
а вот так работает:procedure CreateBMP;
begin
if OriginalBitmap.PixelFormat <> pf24bit then
begin
ShowMessage('Изображение должно быть 24-х битным');
Exit;
end;
for j:=OriginalBitmap.Height-1 downto 0 do
begin
RowOriginal:=pRGBArray(OriginalBitmap.Scanline[j]);
RowProcessed:=pRGBArray(ProcessedBitmap.Scanline[j]);
for i:=OriginalBitmap.Width-1 downto 0 do
begin
RowProcessed[i].rgbtRed:=RowOriginal[i].rgbtRed;
RowProcessed[i].rgbtGreen:=RowOriginal[i].rgbtGreen;
RowProcessed[i].rgbtBlue:=RowOriginal[i].rgbtBlue;
Form1.Canvas.Pixels[i,j]:=(RowProcessed[i].rgbtRed shl 16)+
(RowProcessed[i].rgbtGreen shl 8) +
RowProcessed[i].rgbtBlue;
end;
end;
end;
только совет - так программировать нельзя -
спасибо, что именно нельзя?
-
Rouse_ © (16.09.10 23:01) [3]Весь код плохой, от глобальных переменных до мемлика, неверного использования канвы, отсутствия закладки на размеры оригинального битмапа, неверную работу с цветом
-
понял, это просто черновой вариант
еще вопрос: мне нужен массив допустим s[i,j]=(RowProcessed[i].rgbtBlue shl 16)+ (RowProcessed[i].rgbtGreen shl 8)+RowProcessed[i].rgbtRed;
каким типом его описать? -
0x00FF00 © (17.09.10 02:00) [5]
> каким типом его описать?
s: array of array of Byte, вестимо.
хотя это и не идеальный вариант с точки зрения производительности.
правильнее было бы сделать с помощью ссылки на array [0..0] of Byte, и потом копировать не поэлементно, а с помощью, скажем, GetDIBits. -
Если описываюs1: array of array of Byte
, на строкеs1[i,j]:=(RowProcessed[i].rgbtBlue shl 16)+(RowProcessed[i].rgbtGreen shl 8)+RowProcessed[i].rgbtRed;
выдает такую ошибку
[Pascal Error] Unit1.pas(61): E1012 Constant expression violates subrange bounds
> правильнее было бы сделать с помощью ссылки на array [0.
> .0] of Byte, и потом копировать не поэлементно, а с помощью,
> скажем, GetDIBits.
можно пример использования GetDIBits в моем случае -
Rouse_ © (17.09.10 20:52) [7]
> еще вопрос: мне нужен массив допустим s[i,j]=(RowProcessed[i].
> rgbtBlue shl 16)+ (RowProcessed[i].rgbtGreen shl 8)+RowProcessed[i].
> rgbtRed;
>
> каким типом его описать?
TRGBTriple как он и был изначально при 24 битах :)
Т.е.
var
Data: array of TRGBTriple; -
понимаю что что то глупое спрашиваю, но если
var
s: array of TRGBTriple;
то
s[i,j]=(RowProcessed[i].rgbtBlue shl 16)+ (RowProcessed[i].rgbtGreen shl 8)+RowProcessed[i].rgbtRed;
та же ошибка... -
Rouse_ © (17.09.10 22:21) [9]так естественно, TRGBTriple это структура, и работать с нужно с ее полями
-
с чем именно не подскажите?
-
Rouse_ © (17.09.10 23:30) [11]каждый байт цвета изначально отображен в банной структуре, соответственно открой ее описание и работай с полями самой структуры а не через микс цвета через SHL
-
спасибо, буду разбираться
-
анонимус (29.07.11 02:00) [13]
type
TPixel = Record
X : integer;
Y : integer;
w : Extended;
end;
TPixelArray = ARRAY OF TPixel;
................
procedure TForm1.Button5Click(Sender: TObject);
var
tBmp: TBitmap;
r: Trect;
h: HWND;
QP: TQuickPixels;
PixelArr: TPixelArray;
I: Integer;
x: Integer;
y: Integer;
num:integer;
Pi: TPixel;
begin
h := FindWindow(nil, PChAR('Калькулятор'));
if h > 0 then
begin
GetWindowRect(h, r);
ShowWindow(h, SW_SHOWNORMAL);
sleep(200);
// пересчёт
GetWindowRect(h, r);
tBmp := TBitmap.Create;
tBmp.Width := 300;
tBmp.Height := 100;
PrintWindow(h, tBmp.Canvas.Handle, 0);
tBmp.PixelFormat := pf24bit;
Image10.Picture.Assign(tBmp);
QP := TQuickPixels.Create;
QP.Attach(tBmp);
num:=0;
for y := 0 to QP.Height-1 do
begin
for x := 0 to QP.Width-1 do
begin
if (x < QP.width-1) then
begin
PixelArr[num].x:= (y * QP.width + x);
PixelArr[num].y:= y * QP.width + (x+1);
PixelArr[num].w:= diff(QP, x, y, x+1, y);
num:=num+1;
end;
end;
end;
tBmp.Free;
end;
end;
end;
При попытке записи в массив, выдает ошибку. Если смотреть в отладчике на значения в этом массиве, то пишет Inaccessible value. Как это победить? -
brother © (29.07.11 03:55) [14]> PixelArr
где установка длинны массива? где try excepr?
ps пока, код не ё. -
brother © (29.07.11 03:58) [15]> num:=num+1;
inc(num)
> QP := TQuickPixels.Create;
где уничтожение?
в общем, пока брр, а не код -
brother © (29.07.11 03:59) [16]> excepr?
except конечно -
brother © (29.07.11 04:00) [17]> где установка длинны массива?
SetLength -
анонимус (29.07.11 06:39) [18]понятно что брр, я делфи вижу третий день в жизни, можно поподробней? )
-
анонимус (29.07.11 07:00) [19]
procedure TForm1.Button5Click(Sender: TObject);
var
tBmp: TBitmap;
r: Trect;
h: HWND;
QP: TQuickPixels;
PixelArr: TPixelArray;
I: Integer;
x: Integer;
y: Integer;
num:integer;
Pi: TPixel;
begin
h := FindWindow(nil, PChAR('Калькулятор'));
if h > 0 then
begin
begin
GetWindowRect(h, r); // отыскивает размеры рамки ограничивающей прямоугольник определяемого окна
ShowWindow(h, SW_SHOWNORMAL); // делает окно активным
sleep(200);
// пересчёт
GetWindowRect(h, r); // отыскивает размеры рамки ограничивающей прямоугольник определяемого окна
//end;
tBmp := TBitmap.Create;
tBmp.Width := 300;
//r.Right - r.Left;
tBmp.Height := 100;
//r.Bottom - r.Top;
PrintWindow(h, tBmp.Canvas.Handle, 0);
tBmp.PixelFormat := pf24bit;
Image10.Picture.Assign(tBmp);
QP := TQuickPixels.Create;
QP.Attach(tBmp);
SetLength(PixelArr,QP.Height*QP.width*4);
num:=0;
for y := 0 to QP.Height-1 do
begin
for x := 0 to QP.Width-1 do
begin
if (x < QP.width-1) then
begin
// Pi.x:= (y * QP.width + x);
// Pi.y:= y * QP.width + (x+1);
// Pi.w:= diff(QP, x, y, x+1, y);
// PixelArr[num]:= Pi;
PixelArr[num].x:= (y * QP.width + x);
PixelArr[num].y:= y * QP.width + (x+1);
PixelArr[num].w:= diff(QP, x, y, x+1, y);
inc(num);
end;
end;
end;
// Image10.Picture.Assign(tBmp);
//sleep(2000);
tBmp.Free;
QP.Destroy;
end;
end;
end;
с какой целью тут exept не понял. И еще а есть тут что нибудь, чтобы автоматов выровнять текст кода нормально? -
brother © (29.07.11 08:05) [20]> QP.Destroy;
QP.free
почитай почему не destroy напрямую