Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 791

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!

Есть два компонента типа TImage: в один - загружен из файла jpeg-рисунок, а в другом - средствами его же Canvas что-то нарисовано.

Требуется из каждого компонента вырезать прямоугольный фрагмент заданной формы и скопировать в третий и четвёртый компоненты типа TImage соответственно. Если возможно совместить два таких клипа на одной канве, - ещё лучше, но не обязательно.

Проблема: пробовал использовать метод CopyRect целевого экземпляра TCanvas (то есть, того экземпляра, на который надо копировать), но ничего не получается - копируется белый прямоугольник.

Кто знает как сделать - подскажите.

VNik Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 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™

min@y™ (статус: Доктор наук), 7 декабря 2010, 08:27 [#1]:

Ты вызываешь Canvas.CopyRect для того Image, в который загружена Jpeg-картинка?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

VNik (статус: Посетитель), 7 декабря 2010, 10:49 [#2]:

Нет, для того, в который копирую.
min@y™

min@y™ (статус: Доктор наук), 7 декабря 2010, 11:01 [#3]:

Цитата (VNik):

Нет, для того, в который копирую.

Посмотри внимательно:
Canvas1.CopyRect(DestRect, Canvas2, SourceRect);
{
  Canvas1 - это КУДА копируем
  Canvas2 - ОТКУДА копируем 
}
Не перепутал?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

VNik (статус: Посетитель), 7 декабря 2010, 12:32 [#4]:

Не перепутал. Именно так.

К тому же нужная канва действительно меняется - "заливается" белым.
min@y™

min@y™ (статус: Доктор наук), 7 декабря 2010, 12:48 [#5]:

Цитата (VNik):

Не перепутал. Именно так.

А Canvas2 - это, случайно не Canvas того самого Image, куда загружена Jpeg-картинка?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

VNik (статус: Посетитель), 7 декабря 2010, 12:59 [#6]:

С Canvas того самого Image, куда загружена Jpeg-картинка тоже нужно скопировать прямоугольный фрагмент (на Canvas другого Image) и тоже не получается.

Однако, когда подставляю для копирования Canvas, куда никаких картинок не загружено, а просто его встроенными средствами нанесены линии и точки, всё равно копируется белый прямоугольник.
min@y™

min@y™ (статус: Доктор наук), 7 декабря 2010, 13:03 [#7]:

Мистика. Попробую написать тестовую прогу.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

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™

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

VNik (статус: Посетитель), 7 декабря 2010, 23:31 [#10]:

За JPEG спасибо! Сегодня что-то приболел малость, а завтра попробую - должно получится.

Что касается значения переменных...

Собственно, кроме координат углов прямоугольника там и просматривать нечего. Я их "в реальном времени" выводил в Caption окна (на мой взгляд, - самый удобный способ) - вроде бы не выходят, но я ещё попробую завтра их вместе с граничными значениями вывести (а то действительно мистика какая-то)...

Напишу сюда, что получилось.
min@y™

min@y™ (статус: Доктор наук), 8 декабря 2010, 08:20 [#11]:

Цитата (VNik):

Я их "в реальном времени" выводил в Caption окна (на мой взгляд, - самый удобный способ)

Ага, пипец как удобно! Неудобно только трусы через голову надевать!

Цитата (VNik):

но я ещё попробую завтра их вместе с граничными значениями вывести

Ты лучше черти Rectangle() вместо CopyRect(), чтобы посмотреть, где область отрисовки будет.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

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™

min@y™ (статус: Доктор наук), 8 декабря 2010, 19:20 [#13]:

Отладчик - это вселенское ДОБРО!

Цитата (VNik):

копию соответствующего ответа в конференции

Не понял.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

VNik (статус: Посетитель), 8 декабря 2010, 22:36 [#14]:

Я имел в виду, что оценить по пятибалльной шкале можно только ответ, а реплику в этой конференции - почему-то нельзя.
min@y™

min@y™ (статус: Доктор наук), 9 декабря 2010, 08:28 [#15]:

Цитата (VNik):

Я имел в виду, что оценить по пятибалльной шкале можно только ответ, а реплику в этой конференции - почему-то нельзя.

Можно поставить +1 к репутации.
А не понял я, что такое "копия соответствующего ответа в конференции". Чо за копия, чо за конференция?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

VNik (статус: Посетитель), 9 декабря 2010, 09:15 [#16]:

+1 я уже поставил

Конференцией я назвал этот "мини-форум". Просто предлагал ту запись с мини-форума, в которой содержится удачная подсказка, продублировать, как ответ.
min@y™

min@y™ (статус: Доктор наук), 9 декабря 2010, 09:35 [#17]:

2 ответа на один вопрос давать низя.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
VNik

VNik (статус: Посетитель), 9 декабря 2010, 09:45 [#18]:

понятно

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:35
Выполнено за 0.04 сек.