Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > PNG Dirty Transparency


Автор: lorents 13.7.2010, 09:55
Как можно сделать тоже самое?
http://www.artlebedev.ru/tools/technogrette/img/png-3/

Автор: pseud 13.7.2010, 10:04
Цитата(lorents @  13.7.2010,  09:55 Найти цитируемый пост)
Как можно сделать тоже самое?

так там в ссылке указано "как сделать".
сформулируй вопрос.

Автор: Alexeis 13.7.2010, 10:07
lorents, есть класс TPngObject . У него свойство AlphaSanline пробегаешься по альфе и смотришь значение. Если значение 0 - полная прозрачность, то пиксель с теми же координатами заменяешь на определенный цвет (свойство ScanLine). Начиная с делфи 2009 этот класс поставляется с делфей. Для более ранних версий его можно скачать (например с torry.net)

Автор: lorents 13.7.2010, 11:15
Может кто-нибудь подкинуть ссылки на статьи о PNG (желательно на русском), т.к. ничего нормального найти не получается, в википедии не то что надо. В основном интересует информация о маске и всё что касается прозрачности. 

Автор: Alexeis 13.7.2010, 11:28
Цитата(lorents @  13.7.2010,  10:15 Найти цитируемый пост)
Может кто-нибудь подкинуть ссылки на статьи о PNG (желательно на русском), т.к. ничего нормального найти не получается, в википедии не то что надо. В основном интересует информация о маске и всё что касается прозрачности.  

  формат png бывает 2х по цветности видов 8бит и 24бит на пиксель и 2х видов по прозрачности. Прозрачность цвета (записывается прямо в палитре) и прозрачность пикселя. Прозрачность пикселя храниться отдельно в виде дополнительного 8ми битного битмапа у которого вместо цвета значение прозрачности. Размер этого битмапа равен размеру исходной картинки. Тонкости размещения по секциям и сжатия в данном контексте думаю не интересны.

Автор: lorents 13.7.2010, 11:46
Alexeis, понятно. спасибо.

пойду разбираться дальше

А Вы не знаете как программно сделать вот это
http://www.artlebedev.ru/tools/technogrette/img/png-3/

Автор: AntonN 13.7.2010, 12:00
как-то так...
Код


const
  MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
type
  PRGBAArray = ^TRGBAArray;
  TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;


procedure BuildPNG2BMP(png_file:string; bt:Tbitmap);
var iii,ii:integer;
    PNB:TPngObject; fff:PRGBAArray; aaa:pByteArray;
begin
  PNB:=TPngObject.Create;
  try
    PNB.LoadFromFile(png_file);
    pnb.CreateAlpha;
    bt.Assign(pnb);
    bt.PixelFormat:=pf32bit;
    for ii:=0 to bt.Height-1 do begin
       fff:=bt.ScanLine[ii];
       aaa:=pnb.AlphaScanline[ii];
       for iii:=0 to bt.Width-1 do begin
         fff[iii].rgbReserved:=aaa[iii];
       end;
    end;
  finally
    PNB.free;
  end;
end;

procedure BuildBMP2PNG(bt:Tbitmap; png_file:string );
var iii,ii:integer;
    PNB:TPngObject; fff:PRGBAArray; aaa:pByteArray;
begin
  PNB:=TPngObject.Create;
  try
    bt.PixelFormat:=pf32bit;
    PNB.Assign(bt);
    pnb.CreateAlpha;
    for ii:=0 to bt.Height-1 do begin
        fff:=bt.ScanLine[ii];
        aaa:=pnb.AlphaScanline[ii];
        for iii:=0 to bt.Width-1 do begin
          aaa[iii]:=fff[iii].rgbReserved;
        end;
    end;
    PNB.SaveToFile(png_file);
  finally
    PNB.free;
  end;
end;

procedure BuildPNG_black_alpha(png_file:string; color:Tcolor);
var x,y:integer; fff:PRGBAArray;
    bt:tbitmap;  rc1,bc1,gc1:byte;
begin
  bt:=tbitmap.Create;
  try
    bt.PixelFormat:=pf32bit;
    BuildPNG2BMP(png_file,bt);

    rc1:=GetRValue(color);
    gc1:=GetGValue(color);
    bc1:=GetBValue(color);

    for y:=0 to bt.Height-1 do begin
        fff:=bt.ScanLine[y];
        for x:=0 to bt.Width-1 do begin
          if(fff[x].rgbReserved=0) then begin
             fff[x].rgbBlue:=bc1;
             fff[x].rgbGreen:=gc1;
             fff[x].rgbRed:=rc1;
          end;
        end;
    end;

    BuildBMP2PNG(bt,png_file);
  finally
    bt.free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  BuildPNG_black_alpha('gnome-globe.png',clblack);
end;

Автор: Alexeis 13.7.2010, 12:01
Цитата(lorents @  13.7.2010,  10:46 Найти цитируемый пост)
А Вы не знаете как программно сделать вот это
http://www.artlebedev.ru/tools/technogrette/img/png-3/

  Так алгоритм я уже описал. TPngObject после загрузки определит такую картинку как 2 битмапа (работает аналогично TBitmap) . Обращаешься к пикселам как к матрице высота х ширина, точнее получается массив указателей на строки. Если сильно нужно, то можно обратиться к данным и как к непрерывному массиву, но тогда порядок строк будет обратным (так приятно хранить битмап)

Автор: Bitter 13.7.2010, 12:05
Знаем. Нужно пройтись по всем пикселям, и заменить их цвет по формуле Color = Alpha/255 * Color

Автор: lorents 13.7.2010, 12:09
AntonN, а можно скомпилировать в ехе, у меня проста не под рукой Delphi

Автор: AntonN 13.7.2010, 12:14
Bitter, 
это нужно лишь там, где неполная формула блитинга (например в updatelayaeredwindow), в случае автора это лишь исказит информацию в файле.

Добавлено через 4 минуты и 32 секунды
lorents, 
вот http://desksoft.ru/index.php?downloads=attachments&id=279 (rar)
только сначала забекапь те картинки, над которыми будешь экспериментировать

Автор: lorents 13.7.2010, 12:56
AntonN, 
Цитата(AntonN @  13.7.2010,  12:14 Найти цитируемый пост)
только сначала забекапь те картинки, над которыми будешь экспериментировать 

а что значит "забекапь"?
и для чего там Combobox?

Спасибо, очень вам признателен за Вашу помощь

Автор: AntonN 13.7.2010, 13:15
Резервную копию оставь, вдруг не понравится smile
В комбобоксе выбирается цвет которым зальется облась с нулевой альфой (открой png в обычном виндовом Пейнте - увидишь).
Хотя как по мне такая "фича" специфична, например если картинка будет поворачиваться (текстура в игре) то заливка может потом вылезти в виде цветной каймы по краям.

Автор: lorents 13.7.2010, 14:23
AntonN, код, что надо, Спасибо

есть сайт по оптимизации картинок http://www.punypng.com/
и он делает тоже самое, что и твой код

Твой код проиграл в двух картинках. я использую определенный алгоритм оптимизации png. поэтому результаты крайне точные, есть возможность исправить твой код, чтобф он не проигрывал?

прикрепил картинки, которые проиграли

Автор: lorents 13.7.2010, 14:23
вот вторая картинка

Автор: AntonN 13.7.2010, 14:38
в каком смысле "проиграл"?

Автор: AntonN 13.7.2010, 14:56
По умолчанию zlib в png имеет уровнь компрессии 7 (0..9), можно установить в 9, тогда продавец комиксов будет весить 85,6кб (против выложенного 87,3кб), логотип все так же чуть больше.
Чтобы получить более значительную прибавку (точнее убавку smile ) по размеру нужно уже ковырять палитру, разбираться с дизерингом.

Автор: lorents 13.7.2010, 15:25
AntonN, я имел ввиду кое-что другое

Здесь не стоит вопрос оптимизации. Здесь главное улучшить твой код, чтобы он работал как PunyPng, в частности удалял прозрачные пиксели.
Если Ты это сделаешь, буду очень признателен

Автор: AntonN 13.7.2010, 16:46
Куда же ты их удалишь? Ну я дал код где прозрачные пиксели имеют черый цвет. Точнее можно вообще залить любым цветом, оно все равно невидимое.

Автор: lorents 13.7.2010, 17:13
AntonN, как же тебе объяснить, видимо какие-то пиксели не удаляются
вот этих двух картинок, эта проблема

Автор: AntonN 13.7.2010, 19:58
Выложи две одинаковые картинки, одну исходник нетронутый, и второй через этот PunyPng сохраненный.
png это не только пиксели, и не просто кусок памяти сжатый архиватором, возможно PunyPng оптимизирует палитру, работает с чанками.

Автор: lorents 13.7.2010, 20:22
AntonN, 
Цитата(AntonN @  13.7.2010,  19:58 Найти цитируемый пост)
png это не только пиксели, и не просто кусок памяти сжатый архиватором, возможно PunyPng оптимизирует палитру, работает с чанками. 

в данном случаи, это пиксели, у меня есть специальный алгоритм для оптимизации PNG. и это выявил, т.к. он оптимизирует с 0. 

Вот картинки

Автор: lorents 14.7.2010, 18:19
AntonN, ты не смотрел случайно?

Автор: Bitter 14.7.2010, 19:26
Цитата(lorents @  13.7.2010,  20:22 Найти цитируемый пост)
в данном случаи, это пиксели, у меня есть специальный алгоритм для оптимизации PNG. и это выявил, т.к. он оптимизирует с 0. 


Что это вообще значит? Ну вот своим алгоритмом и оптимизируйте, зачем вам другой?

Автор: lorents 14.7.2010, 22:38
Bitter, 
Цитата(Bitter @  14.7.2010,  19:26 Найти цитируемый пост)
Что это вообще значит? Ну вот своим алгоритмом и оптимизируйте, зачем вам другой? 


тот код который написал AntonN, существенно увеличивает уровень оптимизации PNG с альфаканалом

Автор: AntonN 15.7.2010, 00:17
Да ничего особенного он не делает.
В моем коде ничего сверх сделать не нельзя, чтобы добиться еще меньших размеров файла придется палитру мучать, работать с блоками. Если бы я затратил на это время врядли я бы выложил это в свободный доступ smile

Автор: lorents 15.7.2010, 08:57
AntonN, понятно, если передумаете, дайте знать
я кстати сделал все как мне надо через ImageMagick, ни чем ну уступающий PunyPng, но проблема в том, что ImageMagick не понимает кириллицу.

Автор: x128 16.7.2010, 11:15
Описанный в статье прием реализуется довольно просто:
Код

procedure RemoveTransparentPixels(PNG: TPNGObject);
var
  x,y: integer;
  ImageSRC: pRGBLine;
  AlphaSRC: pByteArray;
begin
  for y:=0 to PNG.Height-1 do begin
    ImageSRC:=PNG.Scanline[y];
    AlphaSRC:=PNG.AlphaScanline[y];
    for x:=0 to PNG.Width-1 do begin
      if AlphaSRC[x]=0 then begin
        ImageSRC[x].rgbtBlue:=0;
        ImageSRC[x].rgbtGreen:=0;
        ImageSRC[x].rgbtRed:=0;
      end;
    end;
  end;
end;

Но! Для картинки Comic_Book_Guy эти действия не сильно помогают т.к. судя по характерному контуру, изначально изображение не имело альфа-канала. Конкретно для этой картинки можно изменить условие "if AlphaSRC[x]=0" на "if AlphaSRC[x]<>255", результат 61,5 кб для PNG24 и 24,5 кб для PNG8.

Автор: lorents 16.7.2010, 14:02
x128, а можно скомпилированный проект, если Вас это не затруднит

Автор: x128 16.7.2010, 17:11
держи

Автор: lorents 16.7.2010, 17:45
x128, при первично просмотре, вроде все как надо, сейчас начну глобальное тестирование

Я и не знал что Вы автор Color Quantizer
Программа нужная

Автор: lorents 16.7.2010, 19:41
x128 мне надо с Вами кое о чем переговорить:
1. я протестировал Ваш код, он работает (значение порога = 1), но картинка Comic Book Guy.png была обработана слегка лучше, чем PunyPng, а вторая картинка ff-logo-big.png чуть хуже. Можно сказать что код рабочий, а главное не громоздкий.

Я как и Вы занимаюсь оптимизацией PNG, и хотел спросить могли бы Вы модернизировать, если это возможно, и сделать так, чтобы работал через командную строку?

2. На данный момент я использую следующий код оптимизации PNG Noninterlaced

Код

for /f "delims=" %%i in ('dir /b /s /a-d Images\*.png') do (
    "%~dp0Docs\prepng.exe" "%%~fi"
    call :pngopt "%%~fi"
    "%~dp0Docs\advpng.exe" -z -4 "%%~fi"
    "%~dp0Docs\deflopt.exe" "%%~fi"
)

:pngopt
1>%temp%\png.log 2>&1 "%~dp0Docs\optipng.exe" -i0 -zw32k -zc1-9 -zm1-9 -zs0-3 -f0-5 %1
type %temp%\png.log
for /f "delims==,IDAT tokens=5" %%i in (%temp%\png.log) do (
    set f=%%i
)
set f=%f:~1,1%
del %temp%\png.log
"%~dp0Docs\pngout.exe" /k0 /f%f% %1


Т.е. картинка проходит через следующие стадии
1. prepng.exe разжимает картинку, т.е. делает сжатие 0
2. optipng.exe -i0 -zw32k -zc1-9 -zm1-9 -zs0-3 -f0-5 - выбирается наилучший фильтр, это не всегда точно, но лучше чем перебирать фильтры через pngout.exe
3. pngout.exe /k0 /f%f% - идет оптимизация через pngout.exe, раньше использовал параметр /n# (n=2), но по рекомендации Ken Silverman (создатель PngOut) удален
4. дальше идут advpng.exe -z -4 и deflopt.exe

Для PNG Adam7 (Interlaced) использую только optipng.exe -i0 -zw32k -zc1-9 -zm1-9 -zs0-3 -f0-5 и deflopt.exe

Хотел знать есть ли возможность улучшить мой алгоритм, Ваша программа иногда превосходит мой алгоритм, и мне просто интересно какой у вас алгоритм?

Автор: x128 16.7.2010, 20:26
Цитата(lorents @  16.7.2010,  19:41 Найти цитируемый пост)
...протестировал Ваш код, он работает (значение порога = 1)

Значение 1 это как в статье, при значении 0 изменения не внося т.е. оригинал, все остальные значения позволяют отсечь "левые" пикселы. Для картинки Comic Book Guy.png значение порога должно быть 255, для ff-logo-big.png значение должно быть 1 т.к. там изначально правильный альфа-канал.

Цитата(lorents @  16.7.2010,  19:41 Найти цитируемый пост)
...могли бы Вы модернизировать, если это возможно, и сделать так, чтобы работал через командную строку?

Не проблема, к тому, что есть добавить или отдельно консольное приложение нужно?

Цитата(lorents @  16.7.2010,  19:41 Найти цитируемый пост)
3. pngout.exe /k0 /f%f% - идет оптимизация через pngout.exe, раньше использовал параметр /n# (n=2), но по рекомендации Ken Silverman (создатель PngOut) удален

Мне кажется, что ключ /ks будет не лишним =)
Хотя... как показали мои эксперименты, лучший фильтр для него понятие не растяжимое т.е. лучший фильтр для optipng  не всегда лучший для pngout.

Цитата(lorents @  16.7.2010,  19:41 Найти цитируемый пост)
Хотел знать есть ли возможность улучшить мой алгоритм, Ваша программа иногда превосходит мой алгоритм, и мне просто интересно какой у вас алгоритм?

Не уверен, что получится сильно улучшить. С PNG24 особых хитростей нет, проверить на количество используемых цветов и в случае <=256 пробовать записать как PNG8 ну и конечно фильтры, возможно у меня получается лучше их подобрать. С PNG8 ситуация немного другая, тут уже больше возможных вариантов, помимо фильтров и попыток записать как PNG24, очень большую роль играет порядок цветов в палитре. В CQ я не сильно гоняю оптимизаторы с разными ключами, обычно я им передаю уже готовую картинку без дополнительных параметров, исключение только при записи брутом.

Автор: lorents 16.7.2010, 23:31
x128, 
Цитата(x128 @  16.7.2010,  20:26 Найти цитируемый пост)
Значение 1 это как в статье, при значении 0 изменения не внося т.е. оригинал, все остальные значения позволяют отсечь "левые" пикселы. Для картинки Comic Book Guy.png значение порога должно быть 255, для ff-logo-big.png значение должно быть 1 т.к. там изначально правильный альфа-канал.

Я даже об этом и не подумал, а как это можно определить программно?

Цитата(x128 @  16.7.2010,  20:26 Найти цитируемый пост)
Не проблема, к тому, что есть добавить или отдельно консольное приложение нужно?

Отдельное консольное приложение, если Вас не затруднит.

Цитата(x128 @  16.7.2010,  20:26 Найти цитируемый пост)
Мне кажется, что ключ /ks будет не лишним =)

Так и сделаю smile 

Цитата(x128 @  16.7.2010,  20:26 Найти цитируемый пост)
Хотя... как показали мои эксперименты, лучший фильтр для него понятие не растяжимое т.е. лучший фильтр для optipng  не всегда лучший для pngout.

я так и не нашел способа, как без перебора через pngout, можно определить наилучший фильтр для pngout.

Цитата(x128 @  16.7.2010,  20:26 Найти цитируемый пост)
В CQ я не сильно гоняю оптимизаторы с разными ключами, обычно я им передаю уже готовую картинку без дополнительных параметров, исключение только при записи брутом.

а можно поподробнее?

Смотрите, есть http://img5.immage.de/16078c62d3clicons.png, Ваша программу оптимизирует сразу наименьший размер, а мой алгоритм только при повторной оптимизации, не знаете, почему так и как это исправить?

а какой алгоритм вы используете для PNG Adam7 (Interlaced)? Я там ошибся, я использую optipng.exe -i1 -zw32k -zc1-9 -zm1-9 -zs0-3 -f0-5 и deflopt.exe, т.к. pngout и advpng не поддерживают PNG Adam7 (Interlaced)

И еще один вопрос, как Вы дкмаете стоит ли сохранять все картинки в цветовой профиль sRGB?

Я очень рад наше встречи на просторах интернета smile 
Если хотите, мы можен перенести наш разговор по электронной почте (lorents17@mail.ru)

Так же высылаю Вам мой алгоритм оптимизации

Автор: lorents 16.7.2010, 23:57
забыл спросить, это система удаление "грязных" пикселей, не всегда уменьшает размер картинки
http://www.artlebedev.ru/tools/technogrette/img/png-4/
а иногда и увеличивает размер, отсюда вытекает два вопроса:
1. можно ли сразу определить поможет это функция уменьшению размера картинки или нет;
2. как можно отменить действие этой функции.

Автор: AntonN 17.7.2010, 12:17
провести опыт на копии изображения и сравнить

Автор: lorents 17.7.2010, 13:38
AntonN, это слишком долго smile  если у тебя много картинок

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)