![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поворот и сдвиг картинки [D7, WinME]
VasRog © (2003-12-11 21:42:00)Всем привет.
Как считать из файла картинку и повернуть ее на определенный угол и сдвинуть по осям координат. Т.е. проблема состоит в незнании процедур считывания пикселов, изменения их координат и последующей установки их на новое место.
И еще один вопросец. Если созданы несколько полей и необходимо программе считать введенные пользователем данные из этих полей, а потом с ними работать, то вероятно нужно переводить их из строкового формата в целый. Если есть такие функции в Дельфи для перевода туда и обратно, то подскажите, плиз.
VasRog (2004-02-12 10:50:00) [1]Господа, помогите, пожалуйста, найти ошибку. Вот две функции из проги:
Эта функция осуществляет поворот картинки:
function RotateBitmap(Bitmap: TBitmap; Angle: Double; Color: TColor; Incx:word; Incy:word): TBitmap;
const
MaxPixelCount = 32768;
type
PRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..MaxPixelCount] of TRGBTriple;
var
A: Extended;
CosTheta: Extended;
SinTheta: Extended;
xSrc, ySrc: Integer;
xDst, yDst: Integer;
xODst, yODst: Integer;
xOSrc, yOSrc: Integer;
xPrime, yPrime: Integer;
srcRow, dstRow: PRGBTripleArray;
begin
Result := TBitmap.Create;
// Workaround SinCos bug
A := Angle;
while A >= 360 do A := A - 360;
while A < 0 do A := A + 360;
// end of workaround SinCos bug
SinCos(A * Pi / 180, SinTheta, CosTheta);
if (SinTheta * CosTheta) < 0 then
begin
Result.Width := Round(Abs(Bitmap.Width * CosTheta - Bitmap.Height * SinTheta));
Result.Height := Round(Abs(Bitmap.Width * SinTheta - Bitmap.Height * CosTheta));
end
else
begin
Result.Width := Round(Abs(Bitmap.Width * CosTheta + Bitmap.Height * SinTheta));
Result.Height := Round(Abs(Bitmap.Width * SinTheta + Bitmap.Height * CosTheta));
end;
with Result.Canvas do
begin
Brush.Color := Color;
Brush.Style := bsSolid;
FillRect(ClipRect);
end;
Result.PixelFormat := pf24bit;
Bitmap.PixelFormat := pf24bit;
xODst := Result.Width div 2;
yODst := Result.Height div 2;
xOSrc := Bitmap.Width div 2;
yOSrc := Bitmap.Height div 2;
if CosTheta < 0 then Dec(xOSrc);
if SinTheta < 0 then Dec(yOSrc);
for ySrc := Max(Bitmap.Height, Result.Height)-1 downto 0 do
begin
yPrime := ySrc - yODst;
for xSrc := Max(Bitmap.Width, Result.Width)-1 downto 0 do
begin
xPrime := xSrc - xODst;
xDst := Round(xPrime * CosTheta - yPrime * SinTheta) + xOSrc;
yDst := Round(xPrime * SinTheta + yPrime * CosTheta) + yOSrc;
if (yDst >= 0) and (yDst < Bitmap.Height) and
(xDst >= 0) and (xDst < Bitmap.Width) and
(ySrc >= 0) and (ySrc < Result.Height) and
(xSrc >= 0) and (xSrc < Result.Width) then
begin
srcRow := Bitmap.ScanLine[yDst];
dstRow := Result.Scanline[ySrc];
dstRow[xSrc] := srcRow[xDst];
end;
end;
end;
end;
Эта процедура(точнее ее часть после except) сдвигает картинку по осям координат в зависимости от значений ползунков(TrackBar5 - ось ox и TrackBar6 - ось oy):
procedure TForm1.Button1Click(Sender: TObject);
var
p:TBitmap;
X,Y:word;
begin
p:=TBitmap.Create;
CopyMe(p,Image1.Picture.Graphic);
Contrast(p,TrackBar1.Position);
Darkness(p,TrackBar4.Position);
Lightness(p,TrackBar2.Position);
p:=RotateBitmap(p,TrackBar3.Position,Color,TrackBar5.Position,TrackBar6.Position);
try
Image2.Picture.Bitmap.FreeImage;
except; end;
X:=TrackBar5.Position;
Y:=TrackBar6.Position;
Image2.Picture.Bitmap.Assign(p);
Image2.Canvas.Brush.Color:=Color;
Form1.Image2.Canvas.Draw(X,Y,p);
Form1.Image2.Canvas.FillRect(Image2.ClientRect);
Form1.Image2.Canvas.Draw(X,Y,p);
p.Free;
end;
В результате получается,что чем больше двигаем ползунок(перемещаем картинку по любой оси), тем большая часть картинки "сьедается"(как будто уходит за край экрана).Заместо перемещения. :(
Ilya (2004-01-06 18:12:00) [2]procedure MyFirstDrawing;
var
Bitmap: TBitmap;
X, Y: Integer;
begin
{Создание}
Bitmap := TBitmap.Create;
{Делаешь с ним, что тебе нужно}
{Например загружаешь рисунок}
Bitmap.LoadFromFile('Tank.bmp');
{Устанавливаешь координаты рисования}
X := 100;
Y := 100;
{рисуешь на Image}
Image.Canvas.Draw(X, Y, Bitmap);
{Заливаешь, т.е. стираешь прежний рисунок}
Image.Canvas.FillRect(Image.ClientRect);
{Меняешь координаты}
X := X + 1;
Y := Y + 1;
{снова рисуешь на Image, только в другом месте}
Image.Canvas.Draw(X, Y, Bitmap);
{Другие процедуры смотри Help, ставь курсор на название
процедуры и жми клавишу F1}
Bitmap.Canvas.Pixels[X, Y];
Bitmap.ScanLine(Row);
Bitmap.Canvas.CopyRect(Rect1, Image.Canvas, Rect2);
Bitmap.Canvas.Draw(X, Y, MyBitmap);
{Обязательно удаляешь}
{Удаляешь только тогда, когда он уже не нужен, а не после
каждого рисования}
Bitmap.Free;
end;
Обязательно купи хорошую книгу по Делфи иначе твои
программы будут неправильными.
На Хелпе далеко не уедешь.
MAXIMUS (2004-01-05 23:31:00) [3]Слушай 'VasRog', ты ещё не сделал своё маленькое открытие по теме перемещения BitMap? Могу помочь , если хочешь разумеется.
(((( Но книжки почитай всё-таки !!!!!!!!!!)))))))))))
Нурик (2003-12-20 06:54:00) [4]Читайте книги по Аналитической геометрии: поворот, смещение координат
VasRog (2003-12-19 23:51:00) [5]OK. Тогда хотя бы процедуры(функции) напишите для всяких там "Создай виртуальный Bitmap","очисть Image","скопируй с Bitmap на Image с новыми координатами","убей битмап" чтобы знать, что в Help'е смотреть.
Особенно интересует "скопируй с Bitmap на Image с новыми координатами".
"не освобождает от выполнения правил" - а что у программистов естб кодекс: "Обломи ближнего своего"?
Тимохов (2003-12-19 20:00:00) [6]Значек "совсем начинающий" также как значек туфли на машине не освобождает от выполнения правил.
Правило первое и самое мощное - читай и напряги мозги.
VasRog (2003-12-19 19:56:00) [7]Это то, что нужно!!! Но можно это в виде кода - хотя бы примерного, а то я совсем начинающий.
Ega23 (2003-12-19 11:44:00) [8]Создай виртуальный Bitmap, скопируй в него содержимое твоего Image через CopyRect, очисть Image, скопируй с Bitmap на Image с новыми координатами, убей битмап.
Только я бы порекомендовал TPaintBox использовать, когда сам рисуешь.
VasRog (2003-12-19 11:35:00) [9]Ну хорошо. С поворотом все более или менее ясно. А вот со сдвигом очень большие проблемы. Дело вот в чем: у меня есть картинка, загруженная в TImage. Теперь ее хочется сдвинуть по осям координат на определенную величину. Есть ли в Дельфи как бы буфер обмена т.е. чтобы я эту картинку считал с канвы и снова ее поместил с измененными координатами на нее же.
Calm (2003-12-15 16:56:00) [10]Что касаетс поворота, то можно почиатть про матрицы преобразований.
Dimka Maslov (2003-12-15 16:30:00) [11]http://delphibase.endimus.com/?action=viewfunc&topic=mediaimg&id=10186
Amoeba (2003-12-15 15:43:00) [12]Что касается поворота картинки, то есть бесплатный компонент:
http://www.delphiarea.com/products/rotateimage/default.htm
REA (2003-12-15 15:22:00) [13]PlgBlt
Windows NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Unsupported.
Alexest (2003-12-15 15:10:00) [14]вывод в заданное место - BitBlt или StretchBlt
const
FScale = 0.5
var
DC: HDC;
BackImage: TBitmap;
begin
BackImage := TBitmap.Create;
BackImage.LoadFromFile(FileName);
PanelDC := GetDC(Panel1.Handle);
ifBackImage <> nil then
StretchBlt(PanelDC, 0, 0,
Round(BackImage.Width*FScale), Round(BackImage.Height*FScale),
BackImage.Canvas.Handle, // handle to source DC
BackImage.Canvas.ClipRect.TopLeft.X, // x-coord of source upper-left corner
BackImage.Canvas.ClipRect.TopLeft.Y, // y-coord of source upper-left corner
BackImage.Width, BackImage.Height, SRCCOPY);
ReleaceDC(Panel1.Handle, PanelDC)
end;
поворот - PlgBlt
пример. BackImage - TBitmap;
procedureTPaintPanel.Rotation(const Angle: Double);
var
P: array[0..2] of TPoint;
begin
по всем вопросам смотри Help или www.msdn.com
p[0].X := 0; p[0].Y := 100; //координата лев. верх. точки оси
p[1].X := 520; p[1].Y := 0; //координата прав. верх. точки оси
p[2].X := 100; p[2].Y := 320;//координата ниж. левой точки оси
PlgBlt(BackImage.Canvas.Handle, P, BackImage.Canvas.Handle,
BackImage.Canvas.ClipRect.TopLeft.X, // x-coord of source upper-left corner
BackImage.Canvas.ClipRect.TopLeft.Y, // y-coord of source upper-left corner
BackImage.Width, BackImage.Height, 0, 0, 0);
end;
Ega23 (2003-12-15 15:07:00) [15]
> И еще вопросик. Как сделать, чтобы при передвижении мышкой
> по картинке в TImag'е координаты местоположения курсора
> относительно картинки отображались бы рядом с курсором?
Событие OnMouseMove, функция GetMousePos, если мне память не изменяет.
Или даже лучше на OnIdle вешать.
Amoeba (2003-12-15 14:39:00) [16]А не рановато ли тебе браться за такие задачи?
Agent13 (2003-12-12 16:23:00) [17]>Хочется сделать не через канву, а в TImag'е.
Ну так и используй Image.Canvas.Pixels[x,y]
>нужно переводить их из строкового формата в целый.
StrToInt
VasRog (2003-12-12 16:07:00) [18]Хочется сделать не через канву, а в TImag'е. Неужели никак нельзя?
И еще вопросик. Как сделать, чтобы при передвижении мышкой по картинке в TImag'е координаты местоположения курсора относительно картинки отображались бы рядом с курсором?
Deb (2003-12-12 02:07:00) [19]Canvas.Pixels[x,y]