|
Вопрос # 4 791/ вопрос открыт / |
|
Доброго времени суток, уважаемые эксперты!
Есть два компонента типа TImage: в один - загружен из файла jpeg-рисунок, а в другом - средствами его же Canvas что-то нарисовано.
Требуется из каждого компонента вырезать прямоугольный фрагмент заданной формы и скопировать в третий и четвёртый компоненты типа TImage соответственно. Если возможно совместить два таких клипа на одной канве, - ещё лучше, но не обязательно.
Проблема: пробовал использовать метод CopyRect целевого экземпляра TCanvas (то есть, того экземпляра, на который надо копировать), но ничего не получается - копируется белый прямоугольник.
Кто знает как сделать - подскажите.
 |
Вопрос задал: VNik (статус: Посетитель)
Вопрос отправлен: 7 декабря 2010, 01:32
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: min@y™
Я не смотрю чужой код, если в нём нет нормальных комментариев.
Написал я тебе пример, где всё нормально копируется.
Прицепляю к ответу.
З.Ы. Комментарии там есть! :)) К ответу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки ответа)
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 7 декабря 2010, 14:14
Оценка за ответ: 4
Комментарий к оценке: Спасибо!
Код действительно прозрачный и наглядно работает работает.
К сожалению пока так и не понял что именно я не так делаю.
Также пока не разобрался как скопировать прямоугольный фрагмент из JPEG-рисунка, загруженного в один экземпляр TIMage, в другой экземпляр TImage.
|
Мини-форум вопроса
Всего сообщений: 18; последнее сообщение — 9 декабря 2010, 09:45; участников в обсуждении: 2.
|
min@y™ (статус: Доктор наук), 7 декабря 2010, 08:27 [#1]:
Ты вызываешь Canvas.CopyRect для того Image, в который загружена Jpeg-картинка?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 7 декабря 2010, 10:49 [#2]:
Нет, для того, в который копирую.
|
|
min@y™ (статус: Доктор наук), 7 декабря 2010, 11:01 [#3]:
Цитата (VNik):
Нет, для того, в который копирую.
Посмотри внимательно:
Canvas1.CopyRect(DestRect, Canvas2, SourceRect);
{
Canvas1 - это КУДА копируем
Canvas2 - ОТКУДА копируем
}
Не перепутал?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 7 декабря 2010, 12:32 [#4]:
Не перепутал. Именно так.
К тому же нужная канва действительно меняется - "заливается" белым.
|
|
min@y™ (статус: Доктор наук), 7 декабря 2010, 12:48 [#5]:
Цитата (VNik):
Не перепутал. Именно так.
А Canvas2 - это, случайно не Canvas того самого Image, куда загружена Jpeg-картинка?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 7 декабря 2010, 12:59 [#6]:
С Canvas того самого Image, куда загружена Jpeg-картинка тоже нужно скопировать прямоугольный фрагмент (на Canvas другого Image) и тоже не получается.
Однако, когда подставляю для копирования Canvas, куда никаких картинок не загружено, а просто его встроенными средствами нанесены линии и точки, всё равно копируется белый прямоугольник.
|
|
min@y™ (статус: Доктор наук), 7 декабря 2010, 13:03 [#7]:
Мистика. Попробую написать тестовую прогу.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 7 декабря 2010, 13:07 [#8]:
На всякий случай, вот как выглядит модуль соответствующего окна.
unit View;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TViewForm = class(TForm)
Image: TImage;
ImageContour: TImage;
private
{ Private declarations }
public
{ Public declarations }
procedure ViewCurrentRect(Base, Contour: TImage; X, Y: Integer);
end;
var
ViewForm: TViewForm;
implementation
{$R *.dfm}
procedure TViewForm.ViewCurrentRect(Base, Contour: TImage; X, Y: Integer);
var
SourceRect, DestRect: TRect;
begin
DestRect := Image.ClientRect;
SourceRect.Left := X - DestRect.Right div 2;
with SourceRect do
if Left < 0 then
Left := 0;
SourceRect.Top := Y - DestRect.Bottom div 2;
with SourceRect do
if Top < 0 then
Top := 0;
SourceRect.Right := SourceRect.Left + DestRect.Right - DestRect.Left;
with Base, SourceRect do
if Right >= Width then
begin
Left := Left + pred (Width) - Right;
Right := pred (Width);
end;
SourceRect.Bottom := SourceRect.Top + DestRect.Bottom - DestRect.Top;
with Base, SourceRect do
if Bottom >= Height then
begin
Top := Top + pred (Height) - Bottom;
Bottom := pred (Height);
end;
Image.Canvas.CopyRect(DestRect, Base.Canvas, SourceRect);
ImageContour.Canvas.CopyRect(DestRect, Contour.Canvas, SourceRect);
end;
end.
Вызов из другого модуля выглядит так:
procedure TImageForm.ImageMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
MouseImagePosToFormPos (X, Y, FormMouseX, FormMouseY);
if Button in [mbLeft] then
begin
IsContourMode := IsContourClicked;
IsDragMouseButtonPressed := True;
end;
with ViewForm do
if Visible then
ViewCurrentRect(Image, ImageContour, ImageMouseX, ImageMouseY);
end;
|
|
min@y™ (статус: Доктор наук), 7 декабря 2010, 14:55 [#9]:
Цитата (min@y™):
К сожалению пока так и не понял что именно я не так делаю.
А ты прогони под отладчиком и посмотри значения переменных. Мож у тебя координаты вылазят за видимые пределы.
Цитата (min@y™):
Также пока не разобрался как скопировать прямоугольный фрагмент из JPEG-рисунка, загруженного в один экземпляр TIMage, в другой экземпляр TImage.
А ты jpg-файл загружай во временную переменную, затем отрисовывай её на Canvas.
var
jpg: TJpegImage;
begin
jpg:= TJpegImage.Create();
try
jpg.LoadFromFile(<имя файла>);
Image1.Canvas.Draw(0, 0, jpg);
finally
jpg.Free();
end;
end;
А копирование фрагментов на другой Canvas я тебе уже написал.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 7 декабря 2010, 23:31 [#10]:
За JPEG спасибо! Сегодня что-то приболел малость, а завтра попробую - должно получится.
Что касается значения переменных...
Собственно, кроме координат углов прямоугольника там и просматривать нечего. Я их "в реальном времени" выводил в Caption окна (на мой взгляд, - самый удобный способ) - вроде бы не выходят, но я ещё попробую завтра их вместе с граничными значениями вывести (а то действительно мистика какая-то)...
Напишу сюда, что получилось.
|
|
min@y™ (статус: Доктор наук), 8 декабря 2010, 08:20 [#11]:
Цитата (VNik):
Я их "в реальном времени" выводил в Caption окна (на мой взгляд, - самый удобный способ)
Ага, пипец как удобно! Неудобно только трусы через голову надевать!
Цитата (VNik):
но я ещё попробую завтра их вместе с граничными значениями вывести
Ты лучше черти Rectangle() вместо CopyRect(), чтобы посмотреть, где область отрисовки будет.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 8 декабря 2010, 18:20 [#12]:
Большое спасибо min@y™:!
Действительно, когда на свежую голову прозвонил значения переменных, выяснилось, что при копировании рисованной канвы ошибка была в передаче параметров - перемудрил с оператором With и вместо экземпляров TImage из вызывающего окна передал одноимённые экземпляры из вызываемого (то есть, источник и приёмник копии совпали :0).
При копировании фрагмента JPEG воспользовался советом и решил проблему так
with TBitmap.Create do // создал буфер
try
Assign(Base.Picture.Graphic); // заполнил его
Image.Canvas.CopyRect(DestRect, Canvas, SourceRect); // отрисовал фрагмент буфера
finally
Free;
end;
В таком виде всё заработало.
Если кинете мне копию соответствующего ответа в конференции, буду рад оценить на 5.
|
|
min@y™ (статус: Доктор наук), 8 декабря 2010, 19:20 [#13]:
Отладчик - это вселенское ДОБРО!
Цитата (VNik):
копию соответствующего ответа в конференции
Не понял.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 8 декабря 2010, 22:36 [#14]:
Я имел в виду, что оценить по пятибалльной шкале можно только ответ, а реплику в этой конференции - почему-то нельзя.
|
|
min@y™ (статус: Доктор наук), 9 декабря 2010, 08:28 [#15]:
Цитата (VNik):
Я имел в виду, что оценить по пятибалльной шкале можно только ответ, а реплику в этой конференции - почему-то нельзя.
Можно поставить +1 к репутации.
А не понял я, что такое "копия соответствующего ответа в конференции". Чо за копия, чо за конференция?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 9 декабря 2010, 09:15 [#16]:
+1 я уже поставил
Конференцией я назвал этот "мини-форум". Просто предлагал ту запись с мини-форума, в которой содержится удачная подсказка, продублировать, как ответ.
|
|
min@y™ (статус: Доктор наук), 9 декабря 2010, 09:35 [#17]:
2 ответа на один вопрос давать низя.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
VNik (статус: Посетитель), 9 декабря 2010, 09:45 [#18]:
понятно
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|