Модераторы: Snowy, Alexeis, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменить размер PNG 
:(
    Опции темы
Akella
  Дата 1.8.2012, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



Не могу найти нормально работающего примера, чтобы качественно увеличить PNG с alpha-каналом.
Delphi XE2

На сайте абракадабры (EDN>>CodeCentral) есть примеры работы с PNG: http://cc.embarcadero.com/Item/25631, в том числе и есть пример процедуры SmoothResize.

Там есть такой кусок кода:

Код

  if not (apng.Header.ColorType in [COLOR_RGBALPHA, COLOR_RGB]) then
    raise Exception.Create('Only COLOR_RGBALPHA and COLOR_RGB formats' +
    ' are supported');




Проблема в том, что у меня изображение имеет apng.Header.ColorType равный 3, а именно COLOR_PALETTE
Код

unit Vcl.Imaging.pngimage
...
...

{Avaliable color modes for PNG}
COLOR_GRAYSCALE = 0;
COLOR_RGB = 2;
COLOR_PALETTE = 3;
COLOR_GRAYSCALEALPHA = 4;
COLOR_RGBALPHA = 6;



поэтому вываливается Exception


Я с изображениями вообще не работал.
Поэтому нужна процедура изменения размера PNG. Или как "конвертировать" существующее изображение, чтобы эта процедура схавала мой png и не подавилась?
Может можно как сконвертировать изображение из COLOR_PALETTE в COLOR_RGBALPHA или в COLOR_RGB? 
PM MAIL   Вверх
Illusion Dolphin
Дата 1.8.2012, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 13
Всего: 63



Вот как перегнать из PNG с COLOR_PALETTE в TBitmap:

Код


procedure LoadPNGImagePalette(PNG: TPNGImage; Bitmap: TBitmap);
var
  I, J, P: Integer;
  DeltaS, DeltaD: Integer;
  AddrLineS, AddrLineD: NativeInt;
  AddrS, AddrD: NativeInt;
  TC: TColor;
  Chunk: TChunkPLTE;
begin
  if PNG.Transparent then
    Bitmap.PixelFormat := pf32bit
  else
    Bitmap.PixelFormat := pf24bit;

  Bitmap.SetSize(PNG.Width, PNG.Height);

  AddrLineS := NativeInt(PNG.ScanLine[0]);
  AddrLineD := NativeInt(Bitmap.ScanLine[0]);
  DeltaS := 0;
  DeltaD := 0;
  if PNG.Height > 1 then
  begin
    DeltaS := NativeInt(PNG.ScanLine[1]) - AddrLineS;
    DeltaD := NativeInt(Bitmap.ScanLine[1])- AddrLineD;
  end;

  Chunk := TChunkPLTE(PNG.Chunks.ItemFromClass(TChunkPLTE));
  if not PNG.Transparent then
  begin
    for I := 0 to PNG.Height - 1 do
    begin
      AddrS := AddrLineS;
      AddrD := AddrLineD;
      for J := 0 to PNG.Width - 1 do
      begin
        P := PByte(AddrS)^;
        with Chunk.Item[P] do
        begin
          PRGB(AddrD)^.R := PNG.GammaTable[rgbRed];
          PRGB(AddrD)^.G := PNG.GammaTable[rgbGreen];
          PRGB(AddrD)^.B := PNG.GammaTable[rgbBlue];
        end;

        Inc(AddrS, 1);
        Inc(AddrD, 3);
      end;
      Inc(AddrLineS, DeltaS);
      Inc(AddrLineD, DeltaD);
    end;
  end else
  begin
    TC := ColorToRGB(PNG.TransparentColor) and $00FFFFFF;

    for I := 0 to PNG.Height - 1 do
    begin
      AddrS := AddrLineS;
      AddrD := AddrLineD;
      for J := 0 to PNG.Width - 1 do
      begin
        P := PByte(AddrS)^;
        with Chunk.Item[P] do
        begin
          PRGB32(AddrD)^.R := PNG.GammaTable[rgbRed];
          PRGB32(AddrD)^.G := PNG.GammaTable[rgbGreen];
          PRGB32(AddrD)^.B := PNG.GammaTable[rgbBlue];

          if PRGB32(AddrD)^.R + PRGB32(AddrD)^.G shl 8 + PRGB32(AddrD)^.B shl 16 = TC then
            PRGB32(AddrD)^.L := 0
          else
            PRGB32(AddrD)^.L := 255;
        end;

        Inc(AddrS, 1);
        Inc(AddrD, 4);
      end;
      Inc(AddrLineS, DeltaS);
      Inc(AddrLineD, DeltaD);
    end;
  end;
end;




Замем если получилось 24 bit каритинка то просто PNGImage.Assign делаешь, если же 32 бита получилось, то:

Код


procedure SavePNGImageTransparent(PNG: TPNGImage; Bitmap: TBitmap);
var
  I, J: Integer;
  DeltaS, DeltaSA, DeltaD: Integer;
  AddrLineS, AddrLineSA, AddrLineD: NativeInt;
  AddrS, AddrSA, AddrD: NativeInt;
begin
  PNG.Chunks.Free;
  PNG.Canvas.Free;
  PNG.CreateBlank(COLOR_RGBALPHA, 8, Bitmap.Width, Bitmap.Height);

  AddrLineS := NativeInt(PNG.ScanLine[0]);
  AddrLineSA := NativeInt(PNG.AlphaScanline[0]);
  AddrLineD := NativeInt(Bitmap.ScanLine[0]);
  DeltaS := 0;
  DeltaSA := 0;
  DeltaD := 0;
  if PNG.Height > 1 then
  begin
    DeltaS := NativeInt(PNG.ScanLine[1]) - AddrLineS;
    DeltaSA := NativeInt(PNG.AlphaScanline[1]) - AddrLineSA;
    DeltaD := NativeInt(Bitmap.ScanLine[1])- AddrLineD;
  end;

  for I := 0 to PNG.Height - 1 do
  begin
    AddrS := AddrLineS;
    AddrSA := AddrLineSA;
    AddrD := AddrLineD;
    for J := 0 to PNG.Width - 1 do
    begin
      PRGB(AddrS)^ := PRGB(AddrD)^;
      Inc(AddrS, 3);
      Inc(AddrD, 3);
      PByte(AddrSA)^ := PByte(AddrD)^;
      Inc(AddrD, 1);
      Inc(AddrSA, 1);
    end;
    Inc(AddrLineS, DeltaS);
    Inc(AddrLineSA, DeltaSA);
    Inc(AddrLineD, DeltaD);
  end;
end;


Работает 32\64 бита. Быстрее только ассемблер наверное.
А дальше - функция SmoothResize smile


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Akella
Дата 1.8.2012, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



ОК, спасибо, попобую завтра  smile

Добавлено через 50 секунд
Я пробовал этот пример с GDI+
http://kachkarvv.org.ua/faq/src-delphi/del...jpg-gdi-rsz.php, вроде работает, но приходится через промежуточный файл.
PM MAIL   Вверх
Illusion Dolphin
Дата 1.8.2012, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 13
Всего: 63



Цитата

Я пробовал этот пример с GDI+
http://kachkarvv.org.ua/faq/src-delphi/del...jpg-gdi-rsz.php, вроде работает, но приходится через промежуточный файл. 


GDI+ может работать через стримы (GdipLoadImageFromStream/GdipSaveImageToStream) так что можно без файлов обойтись и работать со стримами бещ лишних файлов. Но я не уверен что будет работать в случает прозрачной картинки (COLOR_PALETTE с прозрачностью).


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Akella
Дата 2.8.2012, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



Цитата(Illusion Dolphin @  1.8.2012,  16:29 Найти цитируемый пост)
Вот как перегнать из PNG с COLOR_PALETTE в TBitmap:

мне кажется, что потеряется альфа-канал и картинка в итоге будет искажённой, а там цифры, которые мне нужно ещё распознать в текст :(

Добавлено через 2 минуты и 51 секунду
А как можно убрать альфа-канал, заменив прозрачность, например, на красный или синий цвет?
Там прозрачные цифры, и мне их нужно распознать в текст.
PM MAIL   Вверх
x128
Дата 2.8.2012, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 29.9.2009

Репутация: 5
Всего: 7



Не знаю как в Delphi XE2 обстоят дела с alpha-каналом для палитровых PNG, но в оригинальном компоненте который стал донором доступ осуществлялся напрямую через соответствующие чанки. Для палитры это TChunkPLTE, для прозрачности TChunktRNS.
Код

var
  PNG: TPNGObject;
  PLTE: TChunkPLTE;
  tRNS: TChunktRNS;
...
  PLTE:=PNG.Chunks.ItemFromClass(TChunkPLTE) as TChunkPLTE;
  tRNS:=PNG.Chunks.ItemFromClass(TChunktRNS) as TChunktRNS;

для tRNS.PaletteValues[i] индексы i соответствуют индексам палитры и содержат значения альфа-прозрачности для каждого цвета в палитре.
PM MAIL WWW   Вверх
Illusion Dolphin
Дата 2.8.2012, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 13
Всего: 63



Цитата

мне кажется, что потеряется альфа-канал и картинка в итоге будет искажённой, а там цифры, которые мне нужно ещё распознать в текст :(

А там разве зря 2 ветки - для прозначного и непрозрачного PNG? smile

Цитата

А как можно убрать альфа-канал, заменив прозрачность, например, на красный или синий цвет?


Код

          if PRGB32(AddrD)^.R + PRGB32(AddrD)^.G shl 8 + PRGB32(AddrD)^.B shl 16 = TC then
          begin
            PRGB32(AddrD)^.R := SomeR;
            PRGB32(AddrD)^.G := SomeG;
            PRGB32(AddrD)^.B := SomeB;
         end;


Если не получается - можешь скинуть картинку для примера я посмотрю.


Как сказал x128, возможно правильнее смотреть прозрачность через TChunktRNS чанк, но я не видел png, который бы неправильно отобразился в коде который дал я (если такой png есть просьба показать его smile )


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Akella
Дата 2.8.2012, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



Пока не пробовал. Но картнку на всяк случай приложил

Присоединённый файл ( Кол-во скачиваний: 16 )
Присоединённый файл  5PRkW.png 0,40 Kb
PM MAIL   Вверх
Akella
Дата 2.8.2012, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



Цитата(Illusion Dolphin @  1.8.2012,  16:29 Найти цитируемый пост)
PRGB(AddrD)^.R := PNG.GammaTable[rgbRed];


Что за PRGB, где это объявлено?

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  5PRkW.png 0,40 Kb
PM MAIL   Вверх
Akella
Дата 2.8.2012, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



И PRGB32?

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  5PRkW.png 0,40 Kb
PM MAIL   Вверх
Akella
Дата 2.8.2012, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



Я правильно объявил?

Код

type
  pRGB = ^TRGB;
  TRGB = record
    R: Integer;
    G: Integer;
    B: Integer;
  end;


PRGB32 = ^TRGB32;
  TRGB32 = packed record
    R, G, B: Cardinal;
  end;



Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  5PRkW.png 0,40 Kb
PM MAIL   Вверх
Akella
Дата 2.8.2012, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 1
Всего: 329



Цитата(Illusion Dolphin @  1.8.2012,  16:29 Найти цитируемый пост)
procedure LoadPNGImagePalette(PNG: TPNGImage; Bitmap: TBitmap);


в этой процедуре на итерации, когда I = 7, ошибка, AV

Цитата
Project raised exception class EPngError with message 'There is no such palette entry.'


во "второй" части процедуры, после  end else begin
PM MAIL   Вверх
Illusion Dolphin
Дата 2.8.2012, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 13
Всего: 63



Цитата

5PRkW.png 0,40 Kb

Ох, тут придётся модифицировать код, т.к. он только для 8 бит, а тут 4....


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
x128
Дата 2.8.2012, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 29.9.2009

Репутация: 5
Всего: 7



Прикрепил пример. В примере любой PNG приводится к единому формату RGBA и результат ресайзится.


Это сообщение отредактировал(а) x128 - 2.8.2012, 21:48

Присоединённый файл ( Кол-во скачиваний: 36 )
Присоединённый файл  PNGResize.zip 277,21 Kb
PM MAIL WWW   Вверх
x128
Дата 2.8.2012, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 29.9.2009

Репутация: 5
Всего: 7



Хм... Заметил странную особенность, StretchBlt в режиме HALFTONE не сглаживает приложенную картинку при увеличении... Но это мелочи. Меня больше интересует, зачем нужно эту картинку обрабатывать с прозрачностью и зачем работать с PNG напрямую? Я так полагаю, что будет какая-то обработка и скорее всего распознавание и в таком случае достаточно получить битмап и без прозрачности.
Код

var
  bmp: TBitmap;
  png: TPNGObject;
...
  bmp:=TBitmap.Create;
  bmp.PixelFormat:=pf24bit;
  bmp.SetSize(png.Width, png.Height);
  with bmp.Canvas do  
    Brush.Color:=clWhite;
    FillRect(ClipRect);
    Draw(0,0,png);
  end;

PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.1392 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.