Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.03.2013, 05:27   #1
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию Обрезка составного изображения в canvas

Склеиваю изображения в канвасе. Использую TPngImage. После склейки получается что-то вроде этого



Необходимо программно обрезать края до изображения. Чтоб получилось так



Рисую методом Canvas.Draw
До построения изображения обозначить размеры невозможно, так как вставляемые изображения имеют разные позиции отрисовки по осям X,Y, и просчитать общий размер изображения до отрисовки очень сложно. Кто что может подсказать?

Желательно без сложных вычислений, чтоб не нагружать процессор (вычислений и так хватает).
Изображения
Тип файла: png Безымянный.png (62.3 Кб, 217 просмотров)
Тип файла: png Безымянный2.png (54.2 Кб, 213 просмотров)

Последний раз редактировалось doktor255; 28.03.2013 в 05:29.
doktor255 вне форума Ответить с цитированием
Старый 28.03.2013, 07:30   #2
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

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

Абстрактно ответить можно так - у пнгимейдж есть методы работы со сканлайном - его применить, могу дома поискать простые семплы как с ним работать. Сканлайн хоть и перебор пикселей в памяти, но должен быть довольно быстрым.

Ну и проект где-то как-то посмотреть было бы неплохо, может это наведёт на мысль, как помочь, если не секрет, конечно.
phomm вне форума Ответить с цитированием
Старый 28.03.2013, 18:05   #3
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Проект очень большой, поэтому смысла показывать его нет. Вот только часть его с основными функциями

Код:
function BlendPng(Png1,Png2: TPngImage):TPngImage;
Procedure BuildBMP2PNG(bmp: TBitMap; PNG: TPngImage);
var
obj_Width:integer;
implementation
Uses Main;

function BlendPng(Png1,Png2: TPngImage):TPngImage;
var
    MaxWidth,MaxHeight:integer;
    BTOut: Tbitmap;
    png:TPngImage;
begin
    if Png1.Width>Png2.Width then MaxWidth:=Png1.Width else MaxWidth:=Png2.Width;
    if Png1.Height>Png2.Height then MaxHeight:=Png1.Height else MaxHeight:=Png2.Height;
    if obj_Width<MaxWidth then obj_Width:=MaxWidth;
    result:=TPngImage.Create;
    result.CreateBlank(COLOR_RGBALPHA,8,MaxWidth,MaxHeight);
    BTOut := Tbitmap.Create;
    BTOut.PixelFormat := pf32bit;
    BTOut.SetSize(MaxWidth,MaxHeight);
    BTOut.Assign(result);
    BTOut.Canvas.Draw(MaxWidth div 2 - png2.Width div 2,MaxHeight - png2.Height,png2); //Рисуем на BMP Png2 в позиции X,Y
    BTOut.Canvas.Draw(MaxWidth div 2 - png1.Width div 2,MaxHeight - png1.Height,png1); //Рисуем на BMP Png1
    png:=TPngImage.Create; 
    BuildBMP2PNG(BTOut,png); //Конвертируем BMP в PNG 
    BTOut.Free;
    Result.Assign(png);
    png.Free;
end;

Procedure BuildBMP2PNG(bmp: TBitmap; PNG: TPngImage);
Const
   MaxPixelCountA = MaxInt Div SizeOf(TRGBQuad);
Type
   PRGBAArray = ^TRGBAArray;
   TRGBAArray = Array[0..MaxPixelCountA - 1] Of TRGBQuad;
Var
   iii,ii: integer;
   PNB: TPngImage;
   fff: PRGBAArray;
   aaa: pByteArray;
Begin
   PNB := TPngImage.Create;
   Try
      PNB.Assign(bmp);
      pnb.CreateAlpha;
      For ii := 0 To bmp.Height - 1 Do
      Begin
         fff := bmp.ScanLine[ii];
         aaa := pnb.AlphaScanline[ii];
         For iii := 0 To bmp.Width - 1 Do
         Begin
            aaa[iii] := fff[iii].rgbReserved;
         End;
      End;
      PNG.Assign(PNB);
   Finally
      PNB.free;
   End;
End;

end.


Поясняю. В функцию BlendPng Поступает 2 png изображения. Функция их склеивает на битмапе, с сохранением прозрачности (с помощью BuildBMP2PNG). На данный момент в виду того что я не использую сдвиги по осям, всё работает, но мне необходимо ввести в функцию BlendPng "сдвиги по осям", то есть что-то вроде BlendPng(Png1,Png2: TPngImage; X,Y: integer), и вот тут получается полная шляпа, ибо я определяю размер выходного размера по максимальной ширине и высоте картинки, а при смещениях эти размеры меняются. И в нагрузку к этой проблеме нужно изменить BlendPng так, чтоб она могла клеить не 2 картинки а любое количество одновременно (чтоб сохранить нулевую координату, так как при изменениях размеров она поплывёт). И каждая картинка во входящих данных будет иметь координаты сдвигов, то есть как-то так

png1 +10 -20, png2 +5 -30, png3 +50 -20


Картинки имеют теоретический ноль отрисовки по центру снизу


Плюс сдвиги по осям. Данный код я перевожу с явы. В яве есть так называемые анчоры (якоря), и там просто это сделать, а тут задница....
Изображения
Тип файла: png Безымянный.png (2.8 Кб, 199 просмотров)

Последний раз редактировалось doktor255; 29.03.2013 в 00:55.
doktor255 вне форума Ответить с цитированием
Старый 29.03.2013, 06:46   #4
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Поизучал вопрос ещё сутки, получил следующие результаты. Клеить много картинок со сдвигами по осям я могу без проблем. Просто задаю большой размер холста изначально. В процедуре конвертации я работаю с пикселями (код не мой, нашёл на просторах интернета), вот тут и нужно определить границы обрезки, и совершить обрезку. Прошу помощи в ДОПИСАНИИ процедуры BuildBMP2PNG

Последний раз редактировалось doktor255; 29.03.2013 в 06:48.
doktor255 вне форума Ответить с цитированием
Старый 29.03.2013, 22:15   #5
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Неужели ни кто не может помочь? Упрощаю свой вопрос. Как обрезать png сверху, снизу, слева, справа с сохранением альфаканала?
doktor255 вне форума Ответить с цитированием
Старый 29.03.2013, 23:30   #6
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Зачем обрезать ? Создать новый с нужным размером, и в него canvas.copyrect 'ом скопировать что надо.

Могу дать кой-какой исходник моей одной проги по разрезке и поклейке чего-то типа атласов, но там каша, руки нескоро до него дойдут. Но вытянуть кой какие рабочие принципы для пнг-обработки можно. Либо прямо сюда вкопипастю касательно Вашей задачи, хотя и не утверждаю что задачи те же и код подойдёт сразу, уверен придётся дорабатывать. Завтра накропаю что-то по моему разумению подходящее вашей задаче со своего кода, ок ? Ну, или без правок могу так отдать и пояснить лично, коли надо будет. (пишите по контактам)

Последний раз редактировалось phomm; 29.03.2013 в 23:33.
phomm вне форума Ответить с цитированием
Старый 30.03.2013, 00:45   #7
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

А СopyRect у нас умеет копировать альфу? Если бы все было так просто, я бы не просил о помощи. Сейчас стоит конкретная задача. Имеются данные по обрезке. Например 3 пикселя сверху, 4 слева, 5 справа. Нужно обрезать PNG сохранив прозрачность. CopyRect этого не может сделать. Как быть?

Последний раз редактировалось doktor255; 30.03.2013 в 00:49.
doktor255 вне форума Ответить с цитированием
Старый 30.03.2013, 12:18   #8
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Есть подозрения, что необходимость обрезки является следствием ошибки проектирования.
Изложите проблему с начала.
s-andriano вне форума Ответить с цитированием
Старый 30.03.2013, 18:05   #9
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Сначала проблема изложена в топике. Есть png, надо его обрезать с сохранением прозрачности. Как это сделать???
Вот тестовая картинка. Нужно убрать невидимую рамку.
Изображения
Тип файла: png result.png (29.1 Кб, 88 просмотров)

Последний раз редактировалось doktor255; 30.03.2013 в 18:09.
doktor255 вне форума Ответить с цитированием
Старый 30.03.2013, 18:46   #10
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

То, что изложено в топике, не проблема, а ее следствие.
Почему нельзя изначально сделать холст нужного размера?
Почему нельзя сделать холст минимального размера и увеличивать его по мере необходимости?
s-andriano вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обрезка изображения средствами CSS yearmix HTML и CSS 13 05.02.2013 17:31
Обрезка изображения Rost93 PHP 2 29.06.2012 09:31
Image1.Canvas - перерисовка изображения Vova777 Общие вопросы Delphi 3 22.05.2012 11:45
Скопировать часть изображения в canvas NBSTUDIO Мультимедиа в Delphi 3 19.03.2012 22:21
Захват изображения с камеры И ВЫВОД НА CANVAS FoxWMulder Мультимедиа в Delphi 6 20.01.2011 16:53