Эффект "Монохром" для фото
Данный пример преобразует фото в монохромное изображение. Был взят с сайта microsoft и адаптирован с языка C#. Так работает хорошо, но есть парочка вещей которые можно подделать при желании:
- Пути к файлам для загрузки и сохранения лучше преобразовывать в Unicode (с помощью MultiByteToWideChar), а не как сделано в примере. Тогда появится возможность загружать и сохранять из любой папки. В примере только из папки с программой.
- Скорость обработки можно существенно повысить, если не использовать GdipBitmapGetPixel , а вынимать цвета напрямую из палитры
Платформа: Windows
Автор: MicroSoft
Переписано
на FreeBasic: Станислав Будинов
'http://support.microsoft.com/kb/319061 #Undef Color #INCLUDE "windows.bi" #INCLUDE "win/gdiplus.bi" #INCLUDE "crt.bi" Declare Sub SaveGIFWithNewColorTable(Byval image As Any Ptr, Byval filename As String, Byval nColors As Integer, Byval fTransparent As Integer) Type ColorPalette1 Flags As UINT Count As UINT Entries(0 To 15) As Integer End Type Using GDIPLUS Dim GDIPLUSSTARTUPINPUT As GDIPLUSSTARTUPINPUT Dim As ULONG_PTR gdiplusToken GDIPLUSSTARTUPINPUT.GdiplusVersion = 1 If (GdiplusStartup(@gdiplusToken, @GDIPLUSSTARTUPINPUT, NULL) <> 0) Then Print "FAIL" Endif Dim pic As Any Ptr If (GdipLoadImageFromFile(Wstr("1.bmp"), @pic) <> 0) Then Print "FAIL" Endif SaveGIFWithNewColorTable(pic, "test.gif", 16, True) Function GetColorPalette(Byval nColors As Integer) As ColorPalette1 Dim bitscolordepth As PixelFormat = PixelFormat1bppIndexed Dim pal As ColorPalette1 Dim bitmap As Any Ptr Dim size As Integer If nColors > 16 Then bitscolordepth = PixelFormat8bppIndexed Elseif nColors > 2 Then bitscolordepth = PixelFormat4bppIndexed End If GdipCreateBitmapFromScan0(1, 1, NULL, bitscolordepth, NULL, @bitmap) GdipGetImagePaletteSize(bitmap,@size) GdipGetImagePalette(bitmap,Cast(Any Ptr,@pal),size) GdipDisposeImage bitmap Return pal End Function Sub SaveGIFWithNewColorTable(Byval image As Any Ptr, Byval filename As String, Byval nColors As Integer, Byval fTransparent As Integer) If (nColors > 256) Then nColors = 256 End If If nColors < 2 Then nColors = 2 End If Dim Width_ As Integer GdipGetImageWidth(Image,@Width_) Dim Height As Integer GdipGetImageHeight(Image,@Height) Dim bitmap As Any Ptr GdipCreateBitmapFromScan0(Width_, Height, NULL,PixelFormat8bppIndexed , NULL, @bitmap) Dim pal As ColorPalette1 = GetColorPalette(nColors) Dim i As Integer For i = 0 To nColors - 1 Dim Alpha_ As Uinteger = 255 Dim Intensity As Uinteger = i*255/(nColors-1) Dim col As Color = Color(Alpha_, Intensity, Intensity, Intensity) If (i = 0 And fTransparent) Then Alpha_ = 0 End If pal.Entries(i) = Col.Argb_ Next i GdipSetImagePalette(bitmap,Cast(Any Ptr,@pal)) Dim As Any Ptr BmpCopy,g GdipCreateBitmapFromScan0(Width_, Height, NULL,PixelFormat32bppArgb , NULL, @BmpCopy) GdipGetImageGraphicsContext(BmpCopy,@g) GdipSetPageUnit(g,UnitPixel) GdipDrawImageRect(g,image,0,0,width_,height) GdipDeleteGraphics(g) Dim As BitmapData bitmapData Dim As RECT rect = Type(0, 0, Width_, Height) GdipBitmapLockBits(bitmap,Cast(Any Ptr,@rect),IMAGELOCKMODE.IMAGELOCKMODEWRITE,PixelFormat8bppIndexed,@bitmapData) Dim As Integer Ptr pixels = bitmapData.Scan0 Dim As Byte Ptr pBits If (bitmapData.Stride > 0) Then pBits = Cast(Byte Ptr,pixels) Else pBits = Cast(Byte Ptr,pixels) + bitmapData.Stride*(Height-1) Endif Dim As UINT stride = Cast(uint,Abs(bitmapData.Stride)) For row As UINT = 1 To Height For col As UINT = 1 To Width_ Dim As Color pixel Dim As Byte Ptr p8bppPixel = pBits + (row-1)*stride + col-1 Dim As Integer Color_ GdipBitmapGetPixel(BmpCopy,col,row,@Color_) pixel.argb_ = Color_ Dim As Double luminance = (pixel.GetR *0.299) + _ (pixel.GetG *0.587) + _ (pixel.GetB *0.114) *p8bppPixel = Cast(Byte,(luminance * (nColors-1)/255 +0.5)) Next Next GdipBitmapUnlockBits(bitmap,@bitmapData) Dim clssid As String ="{557CF406-1A04-11D3-9A73-0000F81EF32E}" Dim CLSID_01 As CLSID CLSIDFROMSTRING Wstr(clssid), @CLSID_01 If (GdipSaveImageToFile(bitmap, Wstr(filename), @CLSID_01, 0) = 0) Then Print "image saved successfully." Endif GdipDisposeImage BmpCopy GdipDisposeImage bitmap End Sub