[delphi] Повернуть TImage на 90°
сдается мне что только попиксельно руками. если скорость некритична то двумя for'ами в буфер такого же размера
procedure TForm1.Button1Click(Sender: TObject);
var
w,h,i,j:integer;
b1,b2:TBitmap;
r:integer;
begin
w := Image1.Width;
h := Image1.Height;
b1 := nil;
b2 := nil; // исправился
try
b1 := TBitmap.Create;
b2 := TBitmap.Create;
b1.Assign(Image1.Picture.Graphic);
r := 90;
case r of
// +90°
90:
begin
b2.Width := h;
b2.Height := w;
for i := 0 to w-1 do begin
for j := 0 to h-1 do begin
b2.Canvas.Pixels[j,w-i] := b1.Canvas.Pixels[i,j];
end
end;
end;
// +180°
180:
begin
b2.Width := w;
b2.Height := h;
for i := 0 to w-1 do begin
for j := 0 to h-1 do begin
b2.Canvas.Pixels[w-i,h-j] := b1.Canvas.Pixels[i,j];
end
end;
end;
// +270°
270:
begin
b2.Width := h;
b2.Height := w;
for i := 0 to w-1 do begin
for j := 0 to h-1 do begin
b2.Canvas.Pixels[h-j,i] := b1.Canvas.Pixels[i,j];
end
end;
end;
end;
Image2.Picture.Assign(b2);
Image2.Width := b2.Width;
Image2.Height := b2.Height
finally
b1.Free;
b2.Free;
end;
end;
спасибо
Сдается мне, что твоя функция корректно работает только при 90 градусах.
[Тут был код, похожий на приведенный выше]
минимально знакомый с паскалем легко сделает все что ему нужно на основе приведенного текста.
а для увеличения скорости еще заюзать ScanLine
если в исходный Image записана jpg картинка то нет доступа даже к Pixels. поэтому я и создал 2 Bitmap в которые копируется исходная картинка и результат. можно конечно идти и по сканлайнам, но для этого уже придется включать мозг. для разовой обработки картинки годятся и Pixels, всякая оптимизация нужна если необходимо делать что-то скажем 25 раз в секунду для потока картинок.
Поправьте, если я ошибаюсь.
Я писал когда-то алгоритм какого-то пиксельного фильтра: над каждым пикселем делалось константное число операций - порядка 5 умножений. На моем тогдашнем Celeron 500 большие картинки обрабатывались недопостимо медленно - пришлось делать через ScanLine.
Мне кажется, что если мы освобождаем объекты в finally, то создавать их надо не внутри try-блока, а снаружи.да, правильнее снаружи, и на каждое создание отдельный try
можно еще внутри блока finally проверять на null-и
можно еще внутри блока finally проверять на null-иа разве free не делает это само?
а разве free не делает это само?делает, но для этого его нужно обнулить перед try-finally блоком
b2.Free проверяет выделена ли память. можно даже сделать b2:=nil; b2.Free; и исключения не будет
upd. исправил чтоб не резало глаз особо придирчивым
я делал что-то вроде детектора движения на последовательности картинок в порядке курсовой. после первой же попытки использовать Pixels забросил это. вместо этого использовал встроенные в Windows DIB images, которые позволяют обращаться к картинке как к области памяти. очень удобно, можно даже на ассемблере вставки делать, и быстро работает. единственное что к остальной проге привязка несколько неудобная получается.
Оставить комментарий
stm5643616
Есть картинка, загруженная на TImage. Задача - повернуть ее на 90°, 180° или 270°.