Изменить размер прозрачного GIF

Для неординарных вопросов. Если вы опытный программист, попавший в трудную ситуацию, — вам сюда.

Модератор: gaidar

Правила форума
Этот раздел не предназначен для того, чтобы вы адресовали свою проблему профессионалам.
Этот раздел предназначен для профессионалов, которые столкнулись с проблемой и не могут решить ее самостоятельно.
Если вы считаете себя профессионалом, а свою проблему сложной — вам сюда.
Если модератор посчитает, что вы ошиблись, то на первый раз он перенесет ваше сообщение в основной раздел без последствий для автора. Во второй раз тема будет закрыта, а автору будет выписано нарушение. В третий раз автор будет забанен.
Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3286
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Изменить размер прозрачного GIF

Сообщение Andrey Fedorov » 06.06.2017 (Вт) 21:37

Есть GIF-файл, в нем рисунок с прозрачным фоном. Нужно изменить размеры рисунка так чтобы фон остался прозрачным и сохранить его...

Никто не знает решения проблемы?
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3733
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Изменить размер прозрачного GIF

Сообщение Mikle » 06.06.2017 (Вт) 23:00

GIF не поддерживает градиентную прозрачность, поэтому будут заметные искажения на краях непрозрачной области.
В SR2D это делается в три строчки:
Код: Выделить всё
Dim Spr As New SR2D_Sprite

Spr.LoadFromFile App.Path & "\in.gif", , NewWidth, NewHeight
Spr.SaveToFile App.Path & "\out.png", FF_ARGB_PNG

Только я не делал сохранение в GIF потому, что SR2D изначально рассчитан на 32-битный цвет, сохранение идёт в PNG. Можно немного доработать метод SaveToFile класса SR2D_Sprite, и будет сохраняться и в GIF формате.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3286
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Изменить размер прозрачного GIF

Сообщение Andrey Fedorov » 06.06.2017 (Вт) 23:51

Спасиб. Бум пробовать что получится.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3286
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Изменить размер прозрачного GIF

Сообщение Andrey Fedorov » 08.06.2017 (Чт) 11:12

Не получается :(

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

я добавил тип FF_ARGB_GIF
и тут в двух местах поменял:

Код: Выделить всё
If Res = 0 Then
    If fFormat = FF_ARGB_BMP Or fFormat = FF_ARGB_PNG Or fFormat = FF_RGB_JPG Or fFormat = FF_ARGB_GIF Then
      Res = GdipCreateBitmapFromScan0(Width, Height, Width * 4, PixelFormat32bppARGB, cBuf(0), Bmp)
    Else
      Stride = ((Width * 3 - 1) Or 3) + 1
      ReDim ArRGB(Stride * Height - 1)
      Bpp32to24 cBuf(0), ArRGB(0), Width, Height, Stride
      Res = GdipCreateBitmapFromScan0(Width, Height, Stride, PixelFormat24bppRGB, ArRGB(0), Bmp)
    End If
    If Res = 0 Then
      Select Case fFormat
        Case FF_ARGB_GIF
            sType = "{557CF402-1A04-11D3-9A73-0000F81EF32E}"
        Case FF_ARGB_BMP, FF_RGB_BMP
          sType = "{557CF400-1A04-11D3-9A73-0000F81EF32E}"
        Case FF_ARGB_PNG, FF_RGB_PNG
          sType = "{557CF406-1A04-11D3-9A73-0000F81EF32E}"
        Case FF_RGB_JPG
          sType = "{557CF401-1A04-11D3-9A73-0000F81EF32E}"
          tParams.count = 1
          tParams.Parameter.NumberOfValues = 1
          tParams.Parameter.type = 4
          tParams.Parameter.value = VarPtr(JPGQuality)
          CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), tParams.Parameter.GUID
      End Select


Сохраняет как GIF, но там не прописан прозрачный цвет
видимо надо еще что-то добавить
спроси плиз у автора


Если можете - помогите...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

The trick
Постоялец
Постоялец
 
Сообщения: 492
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Изменить размер прозрачного GIF

Сообщение The trick » 08.06.2017 (Чт) 11:24

viewtopic.php?f=15&t=45335
Вот тут посмотри как реализовано. Насколько я помню GDI+ не позволяет задать свойство "затирание фона", поэтому если ты даже и сохранишь с прозрачностью, то у тебя следующий кадр будет накладываться на предыдущий.
UA6527P

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3286
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Изменить размер прозрачного GIF

Сообщение Andrey Fedorov » 08.06.2017 (Чт) 15:10

Спасибо! Прикрутил реализацию сохранения от The trick к методу Spr.SaveToFile от Mikle, вроде работает, но не хочется привязываться к SR2D.dll только из-за этой операции. Можно ли прикрутить реализацию сохранения от The trick к IPicure? Я попробовал переделать SavePictureToFile() от модуля GDI+, но получается черный квадрат. Может там надо вместо GdipCreateBitmapFromHBITMAP p.Handle, p.hPal, img что-то другое использовать?
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3733
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Изменить размер прозрачного GIF

Сообщение Mikle » 08.06.2017 (Чт) 15:15

Andrey Fedorov писал(а):не хочется привязываться к SR2D.dll только из-за этой операции. Можно ли прикрутить реализацию сохранения от The trick к IPicure?

Загрузку средствами GDI+ можно взять из того же класса SR2D_Sprite, а SR2D.dll там для масштабирования, метод тот же, что здесь: viewtopic.php?f=28&t=38123

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3286
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Изменить размер прозрачного GIF

Сообщение Andrey Fedorov » 09.06.2017 (Пт) 3:46

Ну вроде все прикрутил, осталось почистить. Спасибо за помощь!
В функцию RGBResize добавил .а параметр, не знаю правильно ли, но вроде все работает, может кому пригодится:

Private Sub ColAddCol(Dest As Col, Src As Col)
Dest.r = Dest.r + Src.r
Dest.g = Dest.g + Src.g
Dest.b = Dest.b + Src.b
Dest.a = Dest.a Or Src.a
End Sub

Private Function ColToRGB(c As Col) As Long
ColToRGB = c.r * &H10000 + c.g * &H100 + c.b + c.a * &H1000000
End Function

Private Function RGBToCol(ByVal c As Long) As Col
RGBToCol.a = (c And &HFF000000) \ &H1000000
RGBToCol.r = (c And &HFF0000) \ &H10000
RGBToCol.g = (c And &HFF00&) \ &H100
RGBToCol.b = c And &HFF
End Function
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3733
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Изменить размер прозрачного GIF

Сообщение Mikle » 09.06.2017 (Пт) 10:31

Andrey Fedorov писал(а):Dest.a = Dest.a Or Src.a

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

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3286
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: Изменить размер прозрачного GIF

Сообщение Andrey Fedorov » 09.06.2017 (Пт) 13:50

Mikle писал(а):
Andrey Fedorov писал(а):Dest.a = Dest.a Or Src.a

Но в целом функция получается не универсальной.

А как сделано в SR2D.dll?

Еще интересное заметил, в известном модуле GDI+ есть функция LoadPictureFromBytes(), там вот такое:

CreateStreamOnHGlobal bytes(0), False, Stream
GdipLoadImageFromStream(Stream, img)

работает для всех типов файлов кроме GIF, для GIF GdipLoadImageFromStream() выдает invalid parameter, приходится делать:

hMem = GlobalAlloc(&H2&, UBound(bytes()) + 1)
ptr = GlobalLock(hMem)
apiCopyMemory ByVal ptr, bytes(0), UBound(bytes()) + 1
GlobalUnlock hMem
Call CreateStreamOnHGlobal(hMem, 1&, Stream)
GdipCreateBitmapFromStream(Stream, img)

Не знаете почему так?
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3733
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Изменить размер прозрачного GIF

Сообщение Mikle » 09.06.2017 (Пт) 15:49

Andrey Fedorov писал(а):А как сделано в SR2D.dll?

Там библиотека на C++, используется беззнаковый int32, так выглядит последний кусок функции:
Код: Выделить всё
  iyy = 0;
  for (yy = 0; yy < hd; yy++)
  {
    ixx = 0;
    for (xx = 0; xx < wd; xx++)
    {
      b = g = r = a = 0;
      iy = iyy;
      for (y = 1; y <= cy; y++)
      {
        ix = ixx;
        for (x = 1; x <= cx; x++)
        {
          cc = src[ikx[ix] + iky[iy] * ws];
          b += (cc & 0xff) * kx[ix] * ky[iy];
          g += ((cc & 0xff00) >> 8) * kx[ix] * ky[iy];
          r += ((cc & 0xff0000) >> 16) * kx[ix] * ky[iy];
          a += ((cc & 0xff000000) >> 24) * kx[ix] * ky[iy];
          ix += 1;
        }
        iy += 1;
      }
      dest[xx + yy * wd] = b / cxy
                        + (g / cxy << 8)
                        + (r / cxy << 16)
                        + (a / cxy << 24);
      ixx += cx;
    }
    iyy += cy;
  }


Вернуться в Раздел для Профессионалов

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

    TopList