Добрый день! Необходимо написать графический редактор следующего вида: Окно разбито на 2 части, в левой вводятся параметры фигуры, в правой она отрисовывается. Например: для начала задан прямоугольник высотой 50 и шириной 100. Указываем высоту - 25, на ней ширина 50 и фигура должна преобразоваться, приняв форму песочных часов и далее в этом духе. Надеюсь нормально объяснил...
Программу еще не начал, код писать не прошу, необходима консультация в том, какие элементы выбрать для разработки, TPaintBox или TImage и т.д. и как лучше всё это отрисовывать, может кто может дать совет?
Извините за Canvas, действительно пропустил, но Paintbox1.Canvas.Graphic тоже не работает....
То есть чтобы оно "хранилось" вместо Paintbox необходимо использовать Image? Еще раз извините за глупый вопрос, просто не хочется из-за недопонимания переписывать всё...
TPaintBox так устроен, что не хранит изображение, которое в нем нарисовано. Ему просто негде его хранить. Это обычная канва. Чем-то напоминает "узоры на песке", их тоже видно, пока ветер не подует или пока дождь не пойдет. Пока твое окно не перекрыто другими окнами - все видно. Как только окно перекроется - все, что было тобой нарисовано в PaintBox-е сотрется. Чтобы восстановить изображение, тебе придется перерисовать его. Поэтому заполняют TPaintBox обычно в событии OnPaint, то есть, полностью перерисовывают содержимое каждый раз, когда приходит сообщение WM_PAINT.
TImage снимает с тебя заботу о перерисовке своего содержимого. Допустим, по нажатию TButton ты нарисовал линию, свернул программу на таскбар, развернул - линия ровно в том же месте, где и была. PaintBox в аналогичном случае будет пуст.
Вместо Paintbox взял Image, всё отрисовывается хорошо, не исчезает никуда, но StretchDraw упрямится - ошибок не выдает но и не сжимает ничего, когда изображение больше, чем Image, видна лишь часть изображения...
и еще вопросик: Изображение не пропадает, но не делает это вообще: Пишу в событии кнопки первой строкой Img.free и выдает ужасную ошибку: Invalide Pointer operation
А ты задай MyRect побольше (или поменьше) раз в 10, узнаешь, напутал, или нет. А лучше задавай MyRect в зависимости от максимального и минимального из вводимых значений.
Действительно, ошибок не выдает, но это не значит, что работает... думаю я не в том месте его указываю(хотя пробовал в разных) или аргументы не те, посмотрите, пожалуйста, может какие замечания будут по стилю или применению функций, новичок в этом деле, готов учиться на своих ошибках...
procedure TForm1.BitBtn1Click(Sender: TObject); var i,j:integer; a1,a2,buf1,buf2:real; MyRect:TRect; begin //ar1 и ar2-содержат точки фигуры(1-левая грань,2-правая) img.Canvas.Pen.Color:=clBlack; l:=StrtoInt(edit1.text); h:=StrtoInt(edit2.text); //Начальная фигура -прямоугольник(зададим углы) ar1[1,1]:=10; ar1[2,1]:=10; ar1[1,100]:=10; ar1[2,100]:=10+h; ar2[1,1]:=10+l; ar2[2,1]:=10; ar2[1,100]:=10+l; ar2[2,100]:=10+h; //заполним массивы точками из таблицы for i:=1 to 100 do begin if (StringGrid1.Cells[0, i]<>'') and (StringGrid1.Cells[1, i]<>'') then begin a1:=StrToInt(StringGrid1.Cells[0, i]); a2:=StrToInt(StringGrid1.Cells[1, i]); ar1[1,i+1]:=10+Round((l-a1)/2); ar1[2,i+1]:=10+a2; ar2[1,i+1]:=10+Round((l-a1)/2)+a1; ar2[2,i+1]:=10+a2; end; end; //Сортируем массивы по высоте for i:=1 to 100 do for j:=1 to 100 do if ar1[2,i]<ar1[2,j] then begin buf1:=ar1[1,j]; buf2:=ar1[2,j]; ar1[1,j]:=ar1[1,i]; ar1[2,j]:=ar1[2,i]; ar1[1,i]:=buf1; ar1[2,i]:=buf2; end; for i:=1 to 100 do for j:=1 to 100 do if ar2[2,i]<ar2[2,j] then begin buf1:=ar2[1,j]; buf2:=ar2[2,j]; ar2[1,j]:=ar2[1,i]; ar2[2,j]:=ar2[2,i]; ar2[1,i]:=buf1; ar2[2,i]:=buf2; end; //Печать того, что получилось img.Canvas.MoveTo(10,10); for i:=1 to 100 do begin if (ar1[1, i]<>0) and (ar1[2, i]<>0) then begin img.Canvas.LineTo(Round(ar1[1,i]),Round(ar1[2,i])); end; end; img.Canvas.MoveTo(10+l,10); for i:=1 to 100 do begin if (ar2[1, i]<>0) and (ar2[2, i]<>0) then begin img.Canvas.LineTo(Round(ar2[1,i]),Round(ar2[2,i])); end; end; //Отрисовка верхней и нижней граней img.Canvas.MoveTo(10,10); img.Canvas.LineTo(10+l,10); img.Canvas.MoveTo(10,10+h); img.Canvas.LineTo(10+l,10+h); //Перевод изображения из буфера MyRect := Rect(0,0,Image1.ClientWidth,Image1.ClientHeight); Image1.Canvas.StretchDraw(MyRect, Image1.Picture.Graphic); Image1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height), img.Canvas,bounds(0,0,img.Width,img.Height)); end;
Кто так сортировку пишет? У тебя она неправильно сортирует вообще. Видимо, ты откуда-то переписал, причём очень небрежно и не глядя, что там происходит.
for i:=1 to 100 do for j:=i+1 to 100 do
Дальше, а с чего StretchBlt будет работать, если у тебя и буфер, и область вывода, и прямоугольник, который ты выводишь - одного размера? Чему там и куда сжиматься? И зачем ты копируешь из себя в себя?
Насчет изображения понял... Почему-то такие глобальные ошибки сам не замечаешь, путаясь в мелочах, я рисовал от кромки, а чтобы она не была вплотную, сделал отступ в 10 пикселей, переделаю, чтобы всё от середины плясало, поэтому в принципе и сжать-то невозможно было... Спасибо огромное, переделаю, напишу.
А по поводу цикла - это эксперимент был и он удался, если сделать как ты говоришь, то появляются какие-то левые 2 линии по бокам, даже не знаю откуда, но тоже попробую привести к человеческому виду. Еще раз спасибо, будем работать!
Помогите, пожалуйста, с удалением изображения, Img.Destroy напрочь отказывается работать, всё та же ошибка - Invalid Pointer Operation. По идее Create - Destroy, но что-то не так тут...
Форма-то заново не создается и не уничтожается, деструкторы походу оттуда не работают, поэтому и помещал их в кнопку, т.к. в момент нажатия они должны уничтожаться:
procedure TForm1.FormDestroy(Sender: TObject); begin buffer.Free; img.Free; end;
Без ошибок и без результатов.
и вопросик по поводу StretchDraw:
Моя логика, решил не строить от середины, почему-то не удобно: Создаем в памяти изображение нужной ширины+50, и высоты+50: // 50 отведено на небольшие подписи
Это что, это зачем? Зачем копировать ещё раз? Ты сначала зачем-то вывел содержимое Image1 на себя со сжатием, а потом без сжатия туда же скопировал буфер.
Я же тебе сказал, как правильно выводить. А ты забил и сделал свою хрень неправильно. У тебя полное непонимание того, что ты делаешь.
Stretchdraw ожидает в качестве параметра тип .Graphic, img.Canvas такого свойства не имеет, поэтому как туда вставить его я не знаю... в этом и проблема основная.
Вообще уже не знаю что делать, весь мозг сломал, помогите, пожалуйста, переделать.