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

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

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 15.01.2012, 22:49   #1
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
Сообщение Отразить PNG Image

Здравствуйте. Возникла необходимость отразить картинку типа PNG. Есть ли рабочие алгоритмы? Как вариант можно модифицировать этот, но не выходит. Если кто знает - подскажите пожалуйста.
Заранее спасибо.
[Ferox]
postal2 вне форума Ответить с цитированием
Старый 15.01.2012, 23:53   #2
chertovich
Форумчанин
 
Аватар для chertovich
 
Регистрация: 26.07.2009
Сообщений: 489
По умолчанию

а компонент Image вам не поможет? или у вас старая среда разработки?
Если в глубине души вы программист, то, следуя своим наклонностям, вы захотите написать кусок кода.
chertovich вне форума Ответить с цитированием
Старый 15.01.2012, 23:58   #3
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
По умолчанию

Разве Image умеет зеркально отражать картинки? Не видел такого. Delphi 7 среда.
[Ferox]
postal2 вне форума Ответить с цитированием
Старый 16.01.2012, 02:03   #4
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
По умолчанию

Разобрался. Может пригодится кому.
Способ 1. Подключаем GDI+, далее
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  a: TPngImage;
  x,y:integer;
  SrcRect, DstRect: TRect;
begin
  if OpenDialog1.Execute = false then
    Exit;
  a := TPngImage.Create;
  a.LoadFromFile(OpenDialog1.FileName);

   X := a.Width;
   Y := a.Height;
   SrcRect := Rect(0, 0, X, Y);
   DstRect := Rect(X, 0, 0, Y);
   form1.Canvas.CopyRect(DstRect, a.ToBitmap.Canvas, SrcRect);

end;
Способ 2. Изменённый код dmitriegorovih http://programmersforum.ru/showpost....45&postcount=1. Работает достаточно медленно, не менее секунды обрабатывает PNG:

Код:
function TForm1.ResizePNG(png:TPNGObject):TPNGObject;
var
  SL1: pRGBLine;
  aSL1: PByteArray;
  bmp,bmpa,bmp_tmp:Tbitmap;
  x,y,Width,Height:integer;
  r,g,b:cardinal;
begin
  bmp:=Tbitmap.Create;
  bmpa:=Tbitmap.Create;
  bmp_tmp:=Tbitmap.Create;
  bmp_tmp.PixelFormat:=pf24bit;
  bmp_tmp.Width:=png.Width;
  bmp_tmp.Height:=png.Height;
  Result:=TPNGObject.Create;
  Result.CreateBlank(COLOR_RGBALPHA, 8, png.Width, png.Height);
  bmp.Width:=png.Width;
  bmp.Height:=png.Height;
  bmpa.Width:=png.Width;
  bmpa.Height:=png.Height;
  bmp.PixelFormat:=pf24bit;
  bmpa.PixelFormat:=pf24bit;
  Width := png.Width;
  Height := png.Height;

  for y := 0 to Height-1 do
  begin
    sl1:=png.Scanline[y];
    asl1:=png.AlphaScanline[y];
    for x:=0 to Width-1 do
    begin
      bmp.Canvas.Pixels[width - x,y]:=rgb(sl1[x].rgbtRed,sl1[x].rgbtGreen,sl1[x].rgbtBlue);
      bmpa.Canvas.Pixels[width - x,y]:=asl1[x];
    end;
  end;

  bmp_tmp.Canvas.StretchDraw(rect(0,0,Width,Height),bmp);
  bmp.Assign(bmp_tmp);
  bmp_tmp.Canvas.StretchDraw(rect(0,0,Width,Height),bmpa);
  for y:=0 to Height-1 do
  begin
    sl1:=Result.Scanline[y];
    asl1:=Result.AlphaScanline[y];
    for x:=0 to Width-1 do
    begin
      ColortoRGB(bmp.Canvas.Pixels[x,y],r,g,b);
      sl1[x].rgbtRed:=r;
      sl1[x].rgbtGreen:=g;
      sl1[x].rgbtBlue:=b;
      asl1[x]:=bmp_tmp.Canvas.Pixels[x,y];
    end;

  end;
  freeandnil(bmp);
  freeandnil(bmpa);
  freeandnil(bmp_tmp);
end;
Не забывайте удалять за собой то есть использовать вот так
Код:
procedure TForm1.Button6Click(Sender: TObject);
var
  p,p2: TPNGObject;
begin
  //на форме должен быть OpenDialog
  if OpenDialog1.Execute = false then exit;
  p := TPNGObject.Create;
  p.LoadFromFile(OpenDialog1.FileName);
  p2 := ResizeO(p);
  Form1.Canvas.Draw(0,0,p2);
  p2.Free;
  p.Free;
end;
Всем советую использовать первый способ - работает почти мгновенно. (картинка 400*500 точек с прозрачностью на GDI+ 16 мс против 980 на модифицированном алгоритме dmitriegorovih)
[Ferox]
postal2 вне форума Ответить с цитированием
Старый 16.01.2012, 08:46   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Всю жизнь пользуюсь этим (сваял, поразмыслив над разными примерами из сети), и не надо канвасов
Код:
procedure flip(const b: TBitmap; ver, hor: boolean);
var
  hd : Hbitmap;
  wd, hg : Integer;
begin
  if not (hor or ver) then
    Exit;
  hd := b.canvas.handle;
  wd := b.Width;
  hg := b.Height;
  if hor then
    stretchblt(hd, 0, hg - 1, hg, -hg, hd, 0, 0, wd, hg, srccopy);
  if ver then
    stretchblt(hd, wd - 1, 0, -wd, wd, hd, 0, 0, wd, hg, srccopy);
end;
...
flip(bmp, true, false); //вызов, флипнем по вертикали, но не по горизонтали
В первом примере двойная утечка.
Первая очевидная это пропуск a.free
Вторая - не очевидная: a.ToBitmap - создаёт битмап (хотя, чтобы быть 100% уверенным, надо глянуть в исходники, мной используемая либа SynGDIPlus -создаёт), без присвоения куда-либо он не будет уничтожен, надо использовать промежуточный битмап, чтобы его чистить

Последний раз редактировалось phomm; 16.01.2012 в 09:06.
phomm вне форума Ответить с цитированием
Старый 16.01.2012, 11:34   #6
chertovich
Форумчанин
 
Аватар для chertovich
 
Регистрация: 26.07.2009
Сообщений: 489
По умолчанию

а что если записать пиксели строки в обратном порядке?
Если в глубине души вы программист, то, следуя своим наклонностям, вы захотите написать кусок кода.
chertovich вне форума Ответить с цитированием
Старый 16.01.2012, 16:05   #7
dmitriegorovih
Ещё не
Форумчанин
 
Аватар для dmitriegorovih
 
Регистрация: 04.01.2010
Сообщений: 517
По умолчанию

Цитата:
Способ 2. Изменённый код dmitriegorovih http://programmersforum.ru/showpost....45&postcount=1. Работает достаточно медленно, не менее секунды обрабатывает PNG:
Не так ты его модифицировал а надо было вот так

Код:
procedure TForm1.zerkalo_PNG(In_PNG: TPNGObject; var Out_PNG: TPNGObject);
var
png,png2:TPNGObject;
x,y,h,w:integer;
SL1, SL2: pRGBLine;
  aSL1, aSL2: PByteArray;
begin
  png:=TPNGObject.Create;
  png2:=TPNGObject.Create;
  png.Assign(In_PNG);
  png2.Assign(In_PNG);
  w:=png.Width-1;
  h:=png.Height-1;
  for y:=0 to h do
  begin
    sl1:=png.Scanline[y];
    asl1:=png.AlphaScanline[y];
    sl2:=png2.Scanline[y];
    asl2:=png2.AlphaScanline[y];
    for x:=0 to w do
    begin
      sl2[x].rgbtBlue:=sl1[w-x].rgbtBlue;
      sl2[x].rgbtGreen:=sl1[w-x].rgbtGreen;
      sl2[x].rgbtRed:=sl1[w-x].rgbtRed;
      asl2[x]:=asl1[w-x];
    end;
  end;
  Out_PNG.Assign(png2);
  freeandnil(png);
  freeandnil(png2)
end;
у меня обработало мгновенно
Воображение важнее, чем знания. (Albert Einstein)
dmitriegorovih вне форума Ответить с цитированием
Старый 16.01.2012, 17:03   #8
postal2
Форумчанин
 
Аватар для postal2
 
Регистрация: 31.10.2008
Сообщений: 215
По умолчанию

Сегодня сел со свежей головой, что ж за бред то я вам написал. Способ с GDI+ использует метод ToBitmap, следовательно ни о какой прозрачности речи не идёт, всё прозрачное заливается белым.

phomm, признаюсь, что протестировал довольно поверхностно, что-то у меня он даже на обычных bmp картинках даёт сбои - на вертикальном отражении поехал масштаб, на горизонтальном всё в норме. Png не держит, при попытке заменить типы изображение ломается. В общем не судите строго, не смог запустить корректно у себя.

chertovich, так и делаем, проблема в том, что у Png 2 слоя - один для цвета, а второй маска прозрачности, а вот как подступиться к ним я не понял. Хотя вот алгоритм dmitriegorovih вроде как всё прояснил.

dmitriegorovih, спасибо Вам, я немного криворук и испоганил Ваш алгоритм, этот работает как часы, выдаёт ~16 мс на том же изображении.
[Ferox]
postal2 вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
EPNGMissingMultipleIDAT. This PNG Image is invalid because it has missing image parts kardinal94 Общие вопросы Delphi 0 08.10.2010 20:31
image на png dmitriegorovih Мультимедиа в Delphi 8 20.07.2010 16:31
PNG+Image+GetRValue=Ошибка Levsha100 Мультимедиа в Delphi 4 24.04.2009 23:20
Прочитать png формат в image Sin3v Общие вопросы Delphi 1 18.07.2008 11:45
PNG в Image Grey Fox Помощь студентам 1 02.08.2007 12:24