Масштабирование окон
Возможность масштабирования окон (форм) является интересным приемом, который может быть заложен в дизайн приложения. При этом имеется в виду масштабирование в буквальном смысле этого слова: как пропорциональное изменение размера элементов управления формы, так и изменение размера шрифта.
Использовать масштабирование при работе с Delphi крайне просто, ведь в класс TWinControl, от которого наследуются классы форм, встроены методы масштабирования. Вот некоторые из них:
• ScaleControls – пропорциональное изменение размера элементов управления на форме;
• ChangeScale – пропорциональное изменение размера элементов управления с изменением шрифта, который используется для отображения текста в них.
Оба приведенных метода принимают два целочисленных параметра: числитель и знаменатель нового масштаба формы. Пример задания параметров для методов масштабирования приведен в листинге 1.25.
Листинг 1.25. Масштабирование формы с изменением шрифта
procedure TfrmScaleBy.cmbSmallerClick(Sender: TObject);
ChangeScale(80, 100); //Уменьшение на 20 % (новый масштаб – 80 %)
procedure TfrmScaleBy.cmbBiggerClick(Sender: TObject);
ChangeScale(120, 100); //Увеличение на 20 % (новый масштаб – 120 %)
Чтобы размер шрифта правильно устанавливался, для элементов управления нужно использовать шрифты семейства TrueType (в данном примере это шрифт Times New Roman).
На рис. 1.16 показан внешний вид формы до изменения масштаба.
Рис. 1.16. Форма в оригинальном масштабе
Внешний вид формы после уменьшения масштаба в 1,25 раза (новый масштаб составляет 80 % от первоначального) показан на рис. 1.17.
Рис. 1.17. Форма в масштабе 80 %
То, что форма не изменяет свой размер при масштабировании, можно легко исправить, установив, например, свойство AutoSize в значение True с помощью редактора свойств объектов (Object Inspector).
Если по каким-либо причинам использование свойства AutoSize вас не устраивает, то можно рассчитать новый размер формы самостоятельно. Только пересчитывать нужно не размер всего окна, а его клиентской области, ведь строка заголовка при масштабировании не изменяется. Расчет размера окна можно выполнить следующим образом.
1. Получить прямоугольник клиентской области окна (GetClientRect).
2. Вычислить новый размер клиентской области.
3. Рассчитать разницу между новой и первоначальной шириной, новой и первоначальной высотой клиентской области; сложить полученные значения с первоначальными размерами самой формы.
Пример расчета для увеличения размера клиентской области в 1,2 раза приведен ниже:
newWidth:= (rc.Right – rc.Left) * 120 div 100;
newHeight:= (rc.Bottom – rc.Top) * 120 div 100;
Width:= Width + newWidth – (rc.Right – rc.Left);
Height:= Height + newHeight – (rc.Bottom – rc.Top);
Примечание
Чтобы после изменения масштаба формы можно было вернуться в точности к исходному масштабу (с помощью соответствующей обратной операции), нужно для уменьшения и увеличения использовать коэффициенты, произведение которых равно единице. Например, при уменьшении масштаба на 20 % (в 0,8 раз) его нужно увеличивать при обратной операции на 25 % (в 1/0,8 = 1,25 раза).
Данный текст является ознакомительным фрагментом.
Вывести в Image фигуру (например, прямоугольник) по вводимым пользователем размерам
Нужно вывести в Image1 фигуру (прямоугольник например) по вводимым пользователем размерам (x и y, у меня типа Real).
Перерыла кучу материала, но нашла только как нарисовать прямоугольник по заданным пикселям.
Никак не разберусь как сделать так чтоб рисовалось по вводимым данным.
кто может подробно для чайника в графике объяснить, отзовитесь пожалуйста.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Вывести нужные элементы из базы данных, отобранных по параметрам, вводимым пользователем
Добрый вечер, столкнулся с проблемой, что не знаю, как вывести на экран элементы из базы данных. .
Вывести на консоль прямоугольник с заданными пользователем сторонами
4.Пользователь вводит высоту, ширину прямоугольника и символ, которым он должен отрисоваться. Нужно.
Поиск оптимального алгоритма в подгонке размеров изображения к размерам, например, PictureBox
Всем привет! Пытаюсь имитировать такой Режим изменения размеров изображения как StretchImage в.
Создание файла с вводимым пользователем текстом
я пытался написать и вот что у меня вышло @ECHO OFF title Add text to file DEL File.txt :a set.
1073 / 485 / 315
Регистрация: 05.04.2013
Сообщений: 2,133
Сообщение от Svetlaya666
по вводимым пользователем размерам
в любом случае понадобится хоть какая-то координата, затем по этой координате и «вводимым пользователем размерам» можно посчитать требуемые для рисования прямоугольника координаты
Житель Земли
3000 / 2999 / 391
Регистрация: 26.07.2011
Сообщений: 11,463
Записей в блоге: 1
Сообщение от Svetlaya666
в чем выражены? см, метры, мили, парсеки
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
Svetlaya666, весьма просто. Так как у вас координаты хранятся в real, а рисуются они по целочисленным координатам, то придется округлять.
1 2 3 4
Image1.Canvas.Brush.Color := clWhite; //цвет заливки Image1.Canvas.Pen.Color := clBlack; //Цвет обводки Image1.Canvas.Rectangle(round(x),round(y),round(x)+wdth,round(y)+hght); //Не совсем понятно, есть ли у вас длина и ширина, поэтому считаю, что она есть. //Если нужно рисовать прямоугольник с фиксированными размерами, то просто ввести константы wdth и hght
Если размеры вас не устраивают, то вводите коэффициенты, которые позволят позволят получать нужный вам размер.
Регистрация: 24.11.2016
Сообщений: 35
DenNik, вводимые значения в миллиметрах
Добавлено через 8 минут
Nanotentacle, первые х и у это я так понимаю координаты начала прямоугольника, т.е. верхний левый угол?
А далее эта точка + ширина, и эта же точка + высота. Так?
Добавлено через 5 минут
Вобщем я сделала так,
Image1.Canvas.Rectangle(round(30),round(30),round(30)+w,round(30)+h);
(w-это вводимая ширина, h-высота)
А он мне в ответ
There is no overloaded version of ‘Rectangle’ that can be called with these arguments
Добавлено через 49 секунд
Видимо я не правильно поняла что такое round(x) и round(у)
Почетный модератор
64291 / 47589 / 32740
Регистрация: 18.05.2008
Сообщений: 115,181
Image1.Canvas.Rectangle(round(x),round(y),round(x)+w,round(y)+h);//где x,y введенные координаты
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
Svetlaya666, если вы задаете целочисленные значения, то round не нужен. Это функция округления дробного числа.
Регистрация: 22.11.2016
Сообщений: 268
Скобочки подвиньте.
Image1.Canvas.Rectangle(round(30),round(30),round(30+w),round(30+h));
Сообщение от Svetlaya666
вводимые значения в миллиметрах
Тогда надо пересчитать. У меня Kpix_mm=3,1
1 2 3
Kpix_mm:=3.1; w:=x*Kpix_mm; h:=y*Kpix_mm;
Регистрация: 24.11.2016
Сообщений: 35
Сообщение от Teodor7
1
2
3
Kpix_mm:=3.1;
w:=x*Kpix_mm;
h:=y*Kpix_mm
а какой тип у «Kpix_mm»?
Со сдвинутыми скобками заработало) Спасибо. Но у меня значение вводимое например Высота 1200 на ширину 1000 (в миллиметрах), при этом он выдает большой прямоугольник, как поэксперементировать чтоб он стал меньше? И еще: если мне надо его разделить вертикально на 2 или 3 части (их ширина вводиться пользователем), как это можно сделать?
Добавлено через 1 минуту
Teodor7, и что значит присвоить 3.1, это 3 пикселя=1 мм? (Объясните пожалуйста, просто я первый раз столкнулась с графикой и мне трудно разобраться
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
Вы высоту 1200мм никак не выведете в натуральный размер на монитор. Если он у вас не полутораметровый, естественно. Введи те коэффициент, на который умножайте w и h для получения устраивающего вас значения. Начните с коэффициента k=0.1.
Регистрация: 22.11.2016
Сообщений: 268
Сообщение от Svetlaya666
какой тип у «Kpix_mm»?
Вещественный. Принято Extended, чтобы не заморачиваться с точностью никогда
pix_mm это пиксел экрана на миллиметр.
Если такие большие величины, то нужно масштабирование, как уже сказано Nanotentacleом.
Добавлено через 13 минут
Сообщение от Svetlaya666
если мне надо его разделить вертикально на 2 или 3
На два — нарисовать прямоугольник в два раза меньшей ширины поверх первого с левым верхним углом там же.
Если на 3 — в три раза меньшая ширина и сместить на треть ширины.
Сразу уж говорите, что хотите сделать в итоге.
Заблокирован
Во первых выкиньте имидж и вообще забудьте о нём. Этот компонент предназначен для вывода картинок а не для рисования. Его интеллектуальность ужасно мешает. Для этой цели есть паинт бокс. Но там нужно отслеживать перерисовку самому. Рисовать можно вообще прямо на окне. И никакие компоненты не нужны. Рисовать можно на панели. На любом компоненте где есть свойство «канвас». Второй момент, нужно разработать минимальный комплект процедур для работы в виртуальном пространстве. Во-первых нужно повернуть ось игрек как надо, и создать виртуальную машину масштабируемой графики. В ней то как раз можно рисовать всё хоть в парсеках. Почитайте книги Амерала. Их 4. Там всё великолепно изложено, для двумерной и трёмерной графики. Правда на си. Но принцип описан достаточно ясно. Если вам влом всё это изучать, обратитесь к опен Гл или директ икс. Это и есть те самые виртуальные машины, уже готовые, причём с аппаратной поддержкой. И не надо их боятся. Вся сложность у них, которая отпугивает, в начальной инициализации. Нужно задать кучу всяких непонятных на первый взгляд параметров. А когда они все заданы нужно только давать простейшие команды. Поставить точку там-то, начертить линию, и прочее. Вот в принципе и всё.
Регистрация: 22.11.2016
Сообщений: 268
Ну да, конечно! Все, что нарисовано на форме исчезает при наложении поверх какого-нибудь окна, даже сообщения.
Что уж мелочиться с кривым OpenGL, к которому нет внятного описания. Давайте уж тогда Unity5 осваивать.
Не слушайте снобов, Svetlaya666, рисуйте на Image.
Заблокирован
Уважаемый Teodor7 если не умеете, не лезьте. Ничто нигде не исчезает.
Svetlaya666 Вот в этой теме по рисованию графиков лежит мой исходник. Там как раз и реализована простейшая виртуальная машина, показано ка работать с паинт бокс, чтобы он перерисовывался. Всё что нужно, вместо вывода графика, написать процедуры рисования чего угодно. И координаты кстати можете в парсеках задавать. Всё реализуется на дробных числах, как и должно быть.
Программа для рисования графика функций на канве
Регистрация: 22.11.2016
Сообщений: 268
Уважаемый Lirrk, вот Вам нормальная виртуальная машина для рисования с исходниками. Если пока не можете так, то поизучайте https://unity3d.com/ru/unity/
Можно прямо на форме. Ведь она подходит для рисования.
Кстати, кто просил графики функций?
Заблокирован
Teodor7 так вы ещё и читать не умеете?
Всё что нужно, вместо вывода графика, написать процедуры рисования чего угодно.
Регистрация: 24.11.2016
Сообщений: 35
Teodor7, у меня проект в универе, мне надо забить размер окна, и чтоб прога рисунок выдала по размерам, желательно еще чтоб выводить на рисунке, наверное в label-ы, размеры сторон. Сейчас попробую ввести коэфициент, и поделить на два или три, и потом напишу что получилось.
Добавлено через 19 минут
Teodor7, кстати, сразу не поняла, разделить
Сообщение от Teodor7
На два — нарисовать прямоугольник в два раза меньшей ширины поверх первого с левым верхним углом там же.
не получиться, ведь мне надо разделить не на равные части, а по заданным пользователем размерам
Добавлено через 3 минуты
Teodor7, с масштабированием разобралась, спасибо большое)
Регистрация: 22.11.2016
Сообщений: 268
Типа простейшие пластиковые окна?
Тогда на форму три кнопки (рисование, очистка, сохранение в файл),
четыре эдитбокса и имидж.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
procedure TForm1.Button1Click(Sender: TObject); var Rect1:TRect; WidthOfRect,HeightOfRect,Xtxt,Ytxt,w,h,wf,Ww:Integer; KMb:Extended; begin //Рисование Rect1.Left:=50; //сдвиг влево Rect1.Top:=50; //сдвиг сверху KMb:=StrToFloat(Form1.Edit1.Text); //Масштаб w:=StrToInt(Form1.Edit2.Text); h:=StrToInt(Form1.Edit3.Text); wf:=StrToInt(Form1.Edit4.Text); //толщина рам WidthOfRect:=Round(w*KMb); HeightOfRect:=Round(h*KMb); Ytxt:=50+Round(h*KMb/2)-5; Xtxt:=50+Round(w*KMb/2)-10; Ww:=Round(wf*KMb); if Ww1 then Ww:=1; Rect1.Right:=Rect1.Left+WidthOfRect; Rect1.Bottom:=Rect1.Top+HeightOfRect; Form1.Image1.Canvas.Pen.Color:=clWhite; Form1.Image1.Canvas.Pen.Width:=Ww; Form1.Image1.Canvas.Rectangle(Rect1); Form1.Image1.Canvas.TextOut(5,Ytxt,IntToStr(h)); Form1.Image1.Canvas.TextOut(Xtxt,5,IntToStr(w)); end; procedure TForm1.Button2Click(Sender: TObject); begin //очистка рисунка Form1.Image1.Canvas.Pen.Color:=clAqua; Form1.Image1.Canvas.Brush.Color:=clAqua; Form1.Image1.Canvas.Rectangle(0,0,Form1.Image1.Width,Form1.Image1.Height); end; procedure TForm1.Button3Click(Sender: TObject); begin //сохранение в файл Form1.Image1.Picture.SaveToFile('C:\окно.bmp'); end;
Недостаток — все прямоугольники привязаны к углом к 50, 50.
Но если надо смещать — добавить ещё два эдитбокса и т.п.
Но для учёбы это избыточно.
Регистрация: 24.11.2016
Сообщений: 35
Teodor7, многое непонятно, вот мой код,
procedure TForm2.SpeedButton1Click(Sender: TObject);
Var h,w,t,A,D,x,y,g,k,Fw,Fh,Rama,Imp,Stv,Kv: Real;
begin //правая и левая створки
h:=StrToFloatDef(Edit2.Text,0);
w:=StrToFloatdef(Edit3.Text,0);
t:=StrToFloatdef(Edit4.Text,0);
If (edit2.Text=») or (edit3.Text=») or (edit4.Text=») then
MessageDlg(‘Введены не все данные! Расчеты будут неверны!’,mterror, [mbOk], 0);
begin
If RadioButton1.Checked or RadioButton2.Checked then
A:=(t-44-19)+22; //ширина створки
label9.Caption:=’ширина створки ‘+FloatToStr(A);
D:=(h-44-44)+22; //высота створки
label10.Caption:=’высота створки ‘+FloatToStr(D);
x:=(w-t)-44-19-10; //ширина с/п в глухой части
label11.Caption:=’ширина с/п в глухой части ‘+FloatToStr(x);
y:=h-44-44-10; //высота с/п в глухой части
label12.Caption:=’высота с/п в глухой части ‘+FloatToStr(y);
g:=A-57-57-6-10; //ширина с/п в створке
label13.Caption:=’ширина с/п в створке ‘+FloatToStr(g);
k:=D-57-57-6-10; //высота с/п в створке
label14.Caption:=’высота с/п в створке ‘+FloatToStr(k);
Fw:=A-45; //фальц ао ширине
label15.Caption:=’размер фальца по ширине ‘+FloatToStr(Fw);
Fh:=D-45; //фальц по высоте
label16.Caption:=’размер фальца по высоте ‘+FloatToStr(Fh);
Label17.Caption:=’метраж профиля:’;
Rama:=((h+14)*2)+((w+14)*2); //размер рамы
label18.Caption:=’рама ‘+FloatToStr(Rama);
Imp:=h-44-44; //импост
label19.Caption:=’импост ‘+FloatToStr(Imp);
Stv:=((A+8)*2)+((D+8)*2); //створка
label20.Caption:=’створка ‘+FloatToStr(Stv);
Kv:=((x*y)+(g*k))/1000000;
Label27.caption:=’Квадратура стекло-пакета ‘ +floatToStr(Kv);
надо чтоб рисовался прямоугольник по А(ширине) и D(высоте), при этом еще разделялся вертикально на створку и глухарь, это тоже вводит пользователь
Добавлено через 34 секунды
Сообщение от Teodor7
Масштабирование, поворот и сдвиг растра методом суперсемплинга
В процессе разработки геоинформационной системы возникла необходимость в трансформации фотографий земной поверхности. В связи с этим была поставлена задача написать функции масштабирования, поворота и субпиксельного сдвига растра методом суперсемплинга.
Соответствующие функции были успешно созданы и внедрены, а поскольку они могут представлять интерес для широкой общественности, я решил опубликовать готовую утилиту с открытым кодом и пояснениями.
Среда разработки: Delphi/Object Pascal.
Свободное использование и распространение приветствуются.
Ниже мы рассмотрим теорию и практику.
Метод суперсемплинга был выбран по той причине, что целевые изображения после трансформации подвергались в дальнейшем автоматической векторизации и требовалось сохранить максимум исходной информации о цвете и геометрии изображения.
Коротко суть метода
Растровое изображение можно представить как прямоугольник, сложенный из квадратов одинакового размера. Каждый квадрат (пиксель изображения) окрашен сплошным однородным цветом. Если растр получен в результате фотографирования, то, с некоторыми допущениями, можно сказать, что за каждым пикселем находилось некое исходное детальное изображение, которое безвозвратно утеряно и представлено в виде квадрата усреднённого цвета. Таким образом, пиксель представляет собой хэш, свёртку для бесконечного множества разных изображений. И определить точно, хэшем какого именно детального изображения является данный пиксель, без дополнительной информации невозможно.
Например, если любое из этих трёх изображений
попало бы в объектив фотоаппарата так, чтобы его угловой размер соответствовал одному пикселю, то на фотографии каждая из этих трёх картинок была бы представлена вот таким пикселем (увеличен в 225 раз):
Очевидно, что все детали безвозвратно утеряны.
Ввиду того, что фотографии часто бывает необходимо линейно трансформировать (изменить масштаб, повернуть, сдвинуть), а сделать повторную фотосъёмку с нужными параметрами нет возможности, приходится применять приблизительные математические методы преобразований.
Обычно конечным оценщиком качества полученного после трансформации изображения является человеческое зрение и поэтому популярные методы преобразований ориентированы на то, чтобы получить чёткое изображение с контрастными деталями для комфортного восприятия человеком. Но не всегда человек является финальным звеном в использовании изображения и не всегда контрастные детали — это главный критерий качества. Иногда важнее сохранить информацию о цвете и пространственных нюансах изображения.
Любые методы трансформации растра (в частности, масштабирование и поворот), которые используют информацию от нескольких соседних пикселей (например, фильтр Ланцоша или бикубическая интерполяция) фактически пытаются «угадать» утерянную информацию, частично воссоздать по соседним пикселям ту картинку, которая находилась «за» пикселями. Настолько, насколько это позволяет метод. Но это неизбежно приводит к искажениям цвета и геометрии изображения.
Поэтому, если в качестве входных данных у нас есть только растр и никакой другой дополнительной информации нет, то справедливым будет предположение, что конкретно вот эта матрица цветных квадратов и есть исходное изображение для осуществления необходимых преобразований. Результат попиксельной работы с растром неизбежно получится более размытым, чем исходное изображение, но при этом максимально сохранится исходная информация без дополнительных искусственных искажений.
Метод суперсемплинга предполагает, что цвет каждого пикселя итогового изображения рассчитывается как сумма цветов частей соответствующих пикселей исходного изображения, взятых пропорционально площадям этих частей, полученных после преобразования. Разберём по порядку масштабирование, поворот и сдвиг.
Масштабирование
Рассмотрим рисунок. Штриховкой обозначен пиксель исходного изображения, увеличенный для примера по оси Х на 2,5 и по оси Y на 1,5, и расположенный на сплошной сетке пикселей итогового изображения:
Как видно из рисунка, пиксель исходного изображения после масштабирования определил цвет сразу 2-х верхних пикселей итогового изображения. Цвет пограничных пикселей, в зависимости от параметров преобразования, может формироваться из цветов 2-х или 4-х пикселей исходного изображения, пропорционально отсекаемым площадям. Например, для формирования цвета нижнего правого пикселя (на рисунке) от исходного пикселя будет взята только 1/4.
При коэффициентах масштабирования меньше единицы цвет каждого пикселя итогового изображения формируется путём усреднения цветов, как минимум, двух пикселей исходного изображения, так же пропорционально площадям, отсекаемых сеткой итогового изображения.
Для ознакомления с другими методами масштабирования могу порекомендовать эти статьи на Хабре:
Поворот
На рисунке видно, что при повороте цвет пикселя итогового изображения так же формируется из цветов соответствующих частей пискелей исходного изображения (заштрихован) пропорционально площадям этих частей. Этих пикселей в зависимости от центра и угла поворота может быть от 4 до 6 штук.
Детально алгоритм поворота растра был описан в моей предыдущей статье, здесь же я хочу сделать акцент на одном практическом аспекте поворота растра.
Если исходное изображение должно быть подвергнуто и повороту, и масштабированию, то для коэффициентов масштабирования больше единицы следует осуществлять сначала масштабирование, а затем поворот. Рассмотрим на примере.
Это исходное изображение:
Оно сначала было подвергнуто масштабированию с коэффициентом 4, а затем осуществлён поворот на 10° по часовой стрелке, в результате получено следующее изображение:
А здесь наоборот, сначала изображение было подвергнуто повороту, а затем – масштабированию:
Как видим, артефакты, возникшие вследствие поворота, после масштабирования увеличились в размерах. По этой же причине, для коэффициентов масштабирования меньше единицы, следует сначала осуществлять поворот, и только потом масштабирование, чтобы уменьшить влияние этих артефактов на итоговое изображение. Но только при условии, что коэффициенты масштабирования по осям X и Y равны.
Если же коэффициенты масштабирования по осям X и Y не равны, то, в случае необходимости сохранения пропорций исходного изображения, всегда сначала необходимо выполнять масштабирование, и только потом поворот. В качестве примера возьмём зелёный квадрат из примера выше. Сначала изменим масштаб по оси Х в 2 раза и по оси Y в 4 раза, а затем повернём на 10° по часовой стрелке:
А теперь сначала повернём на 10°, после чего изменим масштаб по оси Х в 2 раза и по оси Y в 4 раза:
Геометрия рисунка подверглась трансформации, потому что в качестве входного битмапа для процедуры масштабирования поступает не исходный битмап, а битмап, полученный в результате поворота.
Сдвиг
Процедура сдвига используется в том случае, когда для получения итогового изображения нужно совместить друг с другом встык несколько фрагментов. При этом может понадобиться совмещать края фрагментов не только с точностью до целых пикселей, но и долей пикселя. Сдвиг может осуществляться либо по одной из осей, либо по двум осям. На рисунке для примера изображён вариант сдвига пикселя по оси Х вправо на 0,5 пикселя:
В таком случае для формирования цвета каждого пикселя итогового изображения в расчёт берутся цвета ровно двух соседних пикселей исходного изображения пропорционально отсекаемым площадям. Аналогично проводится расчёт для случая, когда смещение происходит только по оси Y.
На следующем рисунке изображён вариант сдвига по двум осям – по оси Х вправо на 0,5 пикселя и по оси Y вниз на 0,5 пикселя:
В таком случае для формирования цвета пикселя итогового изображения в расчёт берутся цвета ровно четырёх пикселей исходного изображения. Пиксели, выходящие за пределы изображения при сдвиге, обрезаются. А пиксели, находящиеся на противоположном крае исходного изображения, смешиваются с заданным цветом фона.
Примечание для программистов
Для удобства использования рассмотренных процедур в приложениях, все необходимые типы данных, переменные и подпрограммы вынесены в модуль RSSUtils.pas. Файл модуля достаточно разместить в корневом каталоге проекта и указать его имя в разделе uses. После чего из модуля могут быть вызваны следующие процедуры:
ScalePic (SursBit, ResBit:pbit; SclX, SclY:extended; FonR, FonG, FonB:byte) – масштабирование;
RotatePic (SursBit, ResBit:pbit; Ugol:extended; CX, CY:extended; FonR, FonG, FonB:byte) – поворот;
ShiftPic (SursBit, ResBit:pbit; ShX, ShY:extended; FonR, FonG, FonB:byte) – сдвиг, где
SursBit, ResBit – указатели на переменные типа TBitmap для исходного и итогового изображений, соответственно;
SclX, SclY – коэффициенты масштабирования по осям X и Y, соответственно;
Ugol – угол поворота изображения в градусах по часовой стрелке;
CX, CY – координаты центра поворота относительно исходного изображения;
ShX, ShY – величина смещения в пикселях по осям X и Y, соответственно;
FonR, FonG, FonB – RGB-составляющие цвета фона, для замощения участков изображения, не покрытых исходным изображением после трансформации.
Для каскадного применения преобразований нужно вызывать соответствующие процедуры
последовательно, передавая указатель на итоговый битмап предыдущей процедуры в
качестве указателя на исходный битмап для последующей процедуры. Процедуры работают только с 24-битными битмапами.
- поворот изображений
- масштабирование изображений
- сдвиг изображений.
- Программирование
- Delphi
- Алгоритмы
- Обработка изображений
Масштабирование изображения
Нужна помощь по применению процедуры изменяющей размер изображения.
Есть 2-а ЛаблЕдита, кнопка, изображение (битмап) загружается в Имейдж если выбрать пункт меню открыть. Возникаю проблемы по применению данной процедуры для кнопки.
procedure TFormConvertir.ResizeBitmap(imgo, imgd: TBitmap; nw, nh: Integer); var xini, xfi, yini, yfi, saltx, salty: single; x, y, px, py, tpix: integer; PixelColor: TColor; r, g, b: longint; function MyRound(const X: Double): Integer; begin Result := Trunc(x); if Frac(x) >= 0.5 then if x >= 0 then Result := Result + 1 else Result := Result - 1; // Result := Trunc(X + (-2 * Ord(X < 0) + 1) * 0.5); end; begin // Set target size imgd.Width := nw; imgd.Height := nh; // Calcs width & height of every area of pixels of the source bitmap saltx := imgo.Width / nw; salty := imgo.Height / nh; yfi := 0; for y := 0 to nh - 1 do begin // Set the initial and final Y coordinate of a pixel area yini := yfi; yfi := yini + salty; if yfi >= imgo.Height then yfi := imgo.Height - 1; xfi := 0; for x := 0 to nw - 1 do begin // Set the inital and final X coordinate of a pixel area xini := xfi; xfi := xini + saltx; if xfi >= imgo.Width then xfi := imgo.Width - 1; // This loop calcs del average result color of a pixel area // of the imaginary grid r := 0; g := 0; b := 0; tpix := 0; for py := MyRound(yini) to MyRound(yfi) do begin for px := MyRound(xini) to MyRound(xfi) do begin Inc(tpix); PixelColor := ColorToRGB(imgo.Canvas.Pixels[px, py]); r := r + GetRValue(PixelColor); g := g + GetGValue(PixelColor); b := b + GetBValue(PixelColor); end; end; // Draws the result pixel imgd.Canvas.Pixels[x, y] := rgb(MyRound(r / tpix), MyRound(g / tpix), MyRound(b / tpix) ); end; end; end;
Пожалуйста помогите.
Последний раз редактировалось Algplux, 22.03.2013 в 16:34 .