Помогите разобраться с TImage

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Помогите разобраться с TImage

Сообщение alex-y » 14.05.2020 14:15:40

Итак, проблема в следующем. Создаем на форме панель, на нее бросаем TImage. В него грузим из файла картинку, которая может иметь размеры намного больше, чем экран. По краям картинки располагаются еще два TImage - в них будут находиться линейки с некоей разметкой. И два ScrollBar'а, которые управляют расположением картинки в отображаемой области TImage. В проекте выглядит так.

Изображение

Никак не могу разобраться с документацией, которую мне подсовывают поисковики, каким образом задать положение картинки внутри компонента.

Прошу либо просто сказать, какое свойство (ну, например, Image1.Canvas.X ) присвоить, либо дать ссылку на адекватную документацию по сабжу. Или, возможно, это делается несколько иначе? Я не нашел в тех документах, которые мне попались, ни одной идеи с компонентом, в который грузится изображение и автоматически создаются средства ее скроллинга с помощью захвата мышью и скроллбаров.

Только умоляю, не предлагайте готовых сторонних компонентов, мне нужно от нуля это все реализовать.
alex-y
новенький
 
Сообщения: 12
Зарегистрирован: 14.05.2020 14:06:03

Re: Помогите разобраться с TImage

Сообщение Alex2013 » 18.05.2020 16:36:19

Самый простой способ решения проблем со скроллингом выходящей "за рамки приличия" картинки использовать TScrollBox
https://wiki.freepascal.org/TScrollBox/ru
Alex2013
долгожитель
 
Сообщения: 1739
Зарегистрирован: 03.04.2013 11:59:44

Re: Помогите разобраться с TImage

Сообщение DedFrend » 18.05.2020 19:29:35

Недавно очень похожую вещь делал.
Можешь посмотреть вот тут https://github.com/Kulic59/PlotDigitizer
DedFrend
новенький
 
Сообщения: 74
Зарегистрирован: 25.11.2018 12:21:50

Re: Помогите разобраться с TImage

Сообщение alex-y » 19.05.2020 07:38:16

Alex2013

Alex2013 писал(а):использовать TScrollBox


Это для основной картинки. Да и то, в общем контексте получается только видимость решения задачи. Большую картинку скролл-бокс скроллит, без вопросов. А с линейками по ее краям что делать? Они ведь тоже должны сдвигаться.

Кстати, по иерархии наследования TScrollBox, вроде, даже не занимается отображением (это на случай если лезть ковырять исходник LCL), отрисовка идет корнями и хвостами куда-то к TWindowedControl, что-то типа того, могу ошибатья...
alex-y
новенький
 
Сообщения: 12
Зарегистрирован: 14.05.2020 14:06:03

Re: Помогите разобраться с TImage

Сообщение olegy123 » 19.05.2020 08:07:55

alex-y писал(а):Никак не могу разобраться с документацией, которую мне подсовывают поисковики, каким образом задать положение картинки внутри компонента.
Image - это "дубовый компонент" без лишнего функционала, это как у шестерки искать кнопки круиз-контроль, кондишин. Просто тогда когда разработчики придумывали - не думали что через лет 20 кому-то понадобится все это.

если слабо собрать свой компонент из TWinControl, то лучше присмотреть более свежие компоненты, возможно там уже эти кнопки есть

TBGRAImage - есть масштабирование и есть слои!!, на один слой помещаешь картинку, на второй элементы


alex-y писал(а): Или, возможно, это делается несколько иначе? Я не нашел в тех документах, которые мне попались, ни одной идеи с компонентом, в который грузится изображение и автоматически создаются средства ее скроллинга с помощью захвата мышью и скроллбаров.
Можно сделать по быстрому так делают по простому

Код: Выделить всё
TMyImage = class (TPanel)
private
  FScrolHorizont:TScrollBar;
  FScrolVertical:TScrollBar;
  FImage:TImage;
public
  constructor Create(AOwner:TComponent);
...

constructor TMyImage.Create(AOwner:TComponent);
begin
  FScrolHorizont:=TScrollBar.Create(Self);
  FScrolHorizont.Parent:=Self;
  FScrolHorizont.Aligin:=caButton;
  FScrolVertical:=TScrollBar.Create(Self);
  FScrolVertical.Parent:=Self;
  FScrolVertical.Aligin:=caRight;
  FImage:=TImage.Create(Self);
  FImage.Parent:=Self;
  FImage.Aligin:=caClient;

  FImage.OnPaint..

end;


можно серьезно подойти:
Код: Выделить всё
TMyImage = class (TGraphicControl)
..
protected
    procedure Paint; override;


// Тут происходит магия, можно рисовать все что угодно
procedure TMyImage.Paint;
begin
  Canvas.Pen.Style := psSolid;
  Canvas.Brush.Style := bsSolid;
  Canvas.Brush.Color := NewColor;
  Canvas.Rectangle(0, 0, Width, Height);
end;

http://www.realcoding.net/articles/sozd ... entov.html
http://streletzcoder.ru/napisanie-svoih ... komponent/
http://www.realcoding.net/articles/obra ... nenta.html
http://streletzcoder.ru/napisanie-svoih ... komponent/

Добавлено спустя 1 минуту 58 секунд:
лучше поищи на тему "создание визуального компонента delphi" будет очень много разных вариантов предложено

Добавлено спустя 1 минуту 36 секунд:
Пособие по написанию своих компонентов на Дельфи для начинающих
https://www.delphiplus.org/articles/del ... gauge.html
olegy123
долгожитель
 
Сообщения: 1568
Зарегистрирован: 25.02.2016 12:10:20

Re: Помогите разобраться с TImage

Сообщение alex-y » 19.05.2020 08:13:28

DedFrend

Посмотрел Ваш проект. Не то. В общем, показываю то, что требуется. Вот окно программы, в нем - либо ScrollBox с картинкой, либо просто картинка и два слайдера.

Изображение

Если использовать TScrollBox - никаких проблем со скроллингом основной картинки. Но по ее краям - две линейки. Причем, они генерируются программой на основе анализа самой картинки, на них может быть что угодно, то есть, они тоже - Bitmap. Горизонтальная имеет длину, как у основной картинки, вертикальная - высоту, как у основной. При перемещении основной картинки эти линейки тоже должны смещаться до соответствующего участка.

Можно их после каждого смещения основной картинки просто копировать на канву несущих TImage с помощью CopyRect или что там... Но просто неужели разработчики LCL не предусмотрели сразу в каком-то из этих классов по иерархии банального указания координат точки, начиная с которой отображается картинка? Если нет, то и вопрос снимается, придется так и копировать участок.

Добавлено спустя 5 минут 12 секунд:
olegy123

Ага, спасибо! То есть, получается, просто без шансов, кроме прямолинейного, других способов нет. Собственно, это тоже ответ, если нет, то и искать не буду, создавать собственный компонент на один раз - сомнительная практика в случае простого проекта, но технологию можно расписать по событиям нужных органов управления.
alex-y
новенький
 
Сообщения: 12
Зарегистрирован: 14.05.2020 14:06:03

Re: Помогите разобраться с TImage

Сообщение DedFrend » 19.05.2020 09:06:59

По-моему, вам кажется, что скролл-полосы являются частью картинки. Это не так - это просто элементы управления.
Мне кажется вам нужен именно TImage вставленный в TScrollBox.
Можете просто запустить мой PickPoints.exe (он ничего не требует) и посмотреть что получается. Там даже вверху есть окошки, которые показывают координаты курсора в системе координат картинки. Увидите как это работает.
В инете легко можно найти еще TATImageBox . Там сколлбокс с расширенной функциональностью. Я тут недавно его обсуждал.
DedFrend
новенький
 
Сообщения: 74
Зарегистрирован: 25.11.2018 12:21:50

Re: Помогите разобраться с TImage

Сообщение alex-y » 19.05.2020 09:16:32

DedFrend

Я именно ScrollBox и использовал! И он меня полностью устраивает, только пришлось ручками приписать обработку таскания картинки мышкой. Просто возник вопрос - что делать с ЛИНЕЙКАМИ. Они тоже - картинки, и их надо отображать частично. Но, пока ничего лучше не посоветовали, чем копирование фрагмента линейки в отведенный ей контейнер. А для такого действа и контейнер, кстати, не требуется, можно рисовать прямо на канве самой формы.

Ваш PickPoints я запустил. Правда, под Wine, и там картинка внутри скроллбокса постоянно мерцает. Перекомпилировать оказалась не судьба, требуется пакет Graph, которого нет в дистре. Уточню - у меня это жесткое требование, писать только на том, что есть в голом дистре с офсайта. И не используя прямо функций WinAPI или X11.

У Вас стандартно использован TScrollBox, в моем проекте так же. Просто, ориентируясь на позиции скроллбаров, мне нужно еще две картинки обновлять, которые в TScrollBox не спрятать.
alex-y
новенький
 
Сообщения: 12
Зарегистрирован: 14.05.2020 14:06:03

Re: Помогите разобраться с TImage

Сообщение iskander » 19.05.2020 15:44:01

Хм, на скроллбох бросаем панельку, на панельку помещаем TImage с картинкой и обе линейки, выставляем им соответствующие привязки.
Устанавливаем панельке AutoSize в True. Вроде и всё?
iskander
постоялец
 
Сообщения: 275
Зарегистрирован: 08.01.2012 18:43:34

Re: Помогите разобраться с TImage

Сообщение alex-y » 19.05.2020 16:58:55

iskander

Стоит только чуть продвинуть слайдер любого из скроллбаров - и линейка уедет за верхний или левый край. А должна стоять жестко на положенном месте.
Я даже больше скажу - скроллбокс еще и не имеет четко определенных свойств, с помощью которых можно узнать размер области, не занятой скроллбарами. Это значение вынимается через ScrollBox1.VertScrollBar.ClientSize, например, которая возвращает ширину именно "полезной" области. Но эта функция упорно возвращает общую ширину скроллбокса. В итоге эти линейки вылезают за пределы отображаемой части картинки, если размер их контейнеров устанавливать по взвращаемому значению:

Изображение

Короче, я этот тред начал просто на удачу - а вдруг там есть что-то такое, чего я не знаю, а кто-то знает и поможет. Но приговор ясен - никаких даже скроллбоксов. Просто панель, отдельные скролл-бары, отдельные картинки для основной и линеек. И тут уже, насколько хватит фантазии, можно и собственный компонент создать, а можно просто отдельный модуль с классом, который и содержит в себе все перечисленное и управляет всеми телодвижениями. Потому что одно дело - потратить три дня на самостоятеьное программирование, когда ты полностью контролируешь код и соображаешь, что делаешь. Или три дня на копания в документации на разные странные и загадочные компоненты.

Спасибо всем за участие. Но, в принципе, можно и продолжить обсуждение, типа, кто круче придумает выход.
alex-y
новенький
 
Сообщения: 12
Зарегистрирован: 14.05.2020 14:06:03

Re: Помогите разобраться с TImage

Сообщение Alex2013 » 19.05.2020 19:32:36

Если "хочется сложностей" действительно можно загрузить картинку в отдельный TBitmap в ручную вырезать из нее нужные части кидая их на TImage.
Изображение
(Как-то так: хотя тут это сделано очень грубо по принципу "шоб було" проект экспериментальный, а значит в прибывает в "вечной бэте" )
Код где-то в unit1.pas например тут :arrow: Truba_DS_0_0059_14_3_1M0_SRC.7z :idea:
(бинарник с DLL библиотеками тут :arrow: Truba_DS_0_0059_14_3_1M0_bin.7z :idea: )

Но если нет нужды в масштабировании то можно сделать проще .
"Про линейки" (если я верно понял проблему) то их можно нарисовать поверх TImage (а возможно и поверх TScrollBox) по OnPaint
Последний раз редактировалось Alex2013 24.05.2020 18:15:27, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 1739
Зарегистрирован: 03.04.2013 11:59:44

Re: Помогите разобраться с TImage

Сообщение alex-y » 19.05.2020 20:43:10

Alex2013 Я отдельно отпишусь по поводу приложенного примера, когда просмотрю, уже скачал. А остальное. Вспоминается один проект примерно 15-летней давности. Та же фигня - графический контекст 600 дпи под распечатку из программы на принтере. С масштабированием и прочим таким. Формат А3. Там я рисунок разместил на скролл-боксе, а линейки просто от нуля перерисовывал, когда возникала нужда. Генерация такого рисунка размером с фактически отображаемую линейку - не проблема было даже на тогдашних селеронах-333. И писал я это на C++ Builder, а у него немного отличаются реализации компонентов от дельфийских, есть по мелочи разные свойства, которых в дельфях у компонентов нет или они не опубликованы. Да и сами линейки были просто в миллиметрах, реально проще каждый раз от нужной цифры генерировать с нуля было....

А вот лазарус, несмотря на то, что 2020-й год на дворе, не порадовал своей LCL. Нет, она не глючная, очень даже ниче так. Для конца 90-х, когда 4-е дельфи еще вовсю рулили, а билдер только появился. Но, видимо, жизнь ничему не учит разработчиков этой библы. Или они умышленно ее такой делают, не знаю...

А про перехват OnPaint.... Ну, тут всегда компромисс. Да, можно, не настолько это и заморочено, если вдуматься. Да только как-то хочется держать линейки в отдельных контейнерах, обладающих свойствами нормального визуального компонента. И тут уже без разницы, что это - панель, картинка, лишь бы была канва. Минимум ручной работы получается. Ведь при перехвате OnPaint тоже придется создавать под линейки структуру, описывающую ее состояние, методы и прочее. Мне в моей конкретной задаче это неудобно и слишком навороченно. И ведь, в конце концов, TScrollBox тоже не святым духом отображение делает. Та же самая CopyRect по канве. В винде - вообще стопудово, там GDI используется опосредованно через цепочку вызовов. В иксах - ну, у меня лазарь на базе GTK... Такая же фигня, в иксах есть библа типа виндовской GDI с тем же примерно набором функций. Только через GTK путь к ней более длинный выходит...

Поэтому, наверное, где-то перехват OnPaint удобнее, а где-то согласиться на избыточность штатных методов при очень простом программирвоании.

Добавлено спустя 31 минуту 4 секунды:
Alex2013 Посмотрел "подзорную трубу". В принципе, все то же самое - просто отображаем в видимое окно TImage фрагмент теневой картинки. А тут ничего и не придумаешь больше. Если на данной конкретной машине программа под Wine спокойно справляется в реалтайме с захватом веб-камеры, то уж со статичной-то картинкой в нативной среде и на машине раз в 5 - 10 более мощной и говорить не о чем. Просто люблю кодить в тихом уютном местечке под пение птичек... А ноут у меня слабенький...
alex-y
новенький
 
Сообщения: 12
Зарегистрирован: 14.05.2020 14:06:03

Re: Помогите разобраться с TImage

Сообщение DedFrend » 19.05.2020 21:33:33

Я так и не понял, что за "линейки" нужны и для чего.
А Graph в PickPoints не нужен. Можно просто убрать зависимость. Остался от попыток работать с TATImageBox
DedFrend
новенький
 
Сообщения: 74
Зарегистрирован: 25.11.2018 12:21:50

Re: Помогите разобраться с TImage

Сообщение alex-y » 19.05.2020 23:00:20

DedFrend При большом масштабировании картинки помогают ориентироваться на ней. Масштабирование предусмотрено. А картинка представляет собой этакую графическую схему или мозаику большого размера. Почему именно графические - кроме разметки по размеру (печатается цифрами), возможно сохранение какой-нибудь другой информации цветом фона.

PickPoints - убрал зависимость от Graph. Собралось нормально, работает тоже хорошо, без мерцания. Но выглядит как-то так:

Изображение

Добавлено спустя 1 час 21 минуту 54 секунды:
Короче говоря, пока остановился вот на таком варианте. В архиве - просто демка, без основного функционала. Внизу окна - фиксированной высоты область, где будут органы управления базовым функционалом. С линейками в данном демо не морочился, просто копирую их из основной картинки, полоски по центру.

https://yadi.sk/d/asFcGhYPrZITRA

Вроде, все ситуации предусмотрел. Картинка нормально скроллится слайдерами и мышкой. Если размер окна превышает размер картинки, позиционируется в центр. Мелкие глюки, которые пока не заметил, обычно устраняются в процессе дальнейшей работы. Ну и размер получившегося кода в разы меньше основного рабочего, полезного кода программы.
alex-y
новенький
 
Сообщения: 12
Зарегистрирован: 14.05.2020 14:06:03

Re: Помогите разобраться с TImage

Сообщение DedFrend » 20.05.2020 08:22:07

Мда... Ни хрена себе морду перекосило...
DedFrend
новенький
 
Сообщения: 74
Зарегистрирован: 25.11.2018 12:21:50

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

Рейтинг@Mail.ru