Что нового

Как отключить интерполяцию в GDIPlus_ImageResize

VadimKHL

Новичок
Сообщения
155
Репутация
0
Всем привет!
Есть пример создания картинки размером 32x32.
Код:
#include <GDIPlus.au3>
_GDIPlus_Startup()

; Задать размер картинки.
Global $iWidth = 32, $iHeight = 32

; Массив содержащий данные картинки, заполненный случайным образом.
Global $aPic[$iWidth * $iHeight]
For $i = 0 To UBound($aPic) - 1
  ;$aPic[$i] = Random(0, 0xFFFFFF, 1)
  $aPic[$i] = BitOR(0xFF000000, Random(0, 0xFFFFFF, 1))
Next

; Создать структуру UINT(4 байта) с именем PIC размером высота * ширина картинки.
$tStruct = DllStructCreate("uint PIC[" & $iWidth * $iHeight & "]")
For $i = 0 To UBound($aPic) - 1
  DllStructSetData($tStruct, "PIC", $aPic[$i], $i + 1)
Next

; Создать картинку из структуры.
$hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB, $iWidth * 4, DllStructGetPtr($tStruct, "PIC"))

; Сохранить в файл.
_GDIPlus_ImageSaveToFile($hBitmap, "pic.bmp")

Local $hBitmap_Scaled = _GDIPlus_ImageResize($hBitmap, 320, 320) ;resize image

; Сохранить в файл.
_GDIPlus_ImageSaveToFile($hBitmap_Scaled, "pic2.bmp")

; Удалить ресурсы GDI+.
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_ImageDispose($hBitmap_Scaled)
_GDIPlus_Shutdown()

После увеличения оригинала функцией _GDIPlus_ImageResize в 10 раз,
картинка получается вся смазанная интерполяцией.
Как ее можно отключить? Требуется увеличить изображение, как это делает допустим тот же просмотр изображений Windows.
Вот открытая оригинальное изображение 32x32, просто увеличенное колесиком мыши. Четкие огромные пиксели)
Как это можно повторить (увеличить без интерполяции)?
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Режим интерполяции задаётся четвёртым параметром
Код:
$hBitmap_Scaled = _GDIPlus_ImageResize($hBitmap, 320, 320, $GDIP_INTERPOLATIONMODE_NEARESTNEIGHBOR)

Но в данном режиме картинка будет сдвинута влево-вверх на половину увеличенного пикселя. Для устранения этого эффекта необходимо добавить в функцию _GDIPlus_ImageResize строку (до или после установки режима)
Код:
_GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, 2)


А если вам не нужна прозрачность, то можно использовать
Код:
_WinAPI_AdjustBitmap()
с дополнительными преобразованиями из GDI+ в gdi32 и обратно.
 
Автор
V

VadimKHL

Новичок
Сообщения
155
Репутация
0
Но в данном режиме картинка будет сдвинута влево-вверх на половину увеличенного пикселя. Для устранения этого эффекта необходимо добавить в функцию _GDIPlus_ImageResize строку (до или после установки режима)
Что делаю не так, эффект сдвига на пол пикселя остается:
Код:
#include <GDIPlus.au3>
_GDIPlus_Startup()

; Задать размер картинки.
Global $iWidth = 32, $iHeight = 32

; Массив содержащий данные картинки, заполненный случайным образом.
Global $aPic[$iWidth * $iHeight]
For $i = 0 To UBound($aPic) - 1
  $aPic[$i] = BitOR(0xFF000000, Random(0, 0xFFFFFF, 1))
Next

; Создать структуру UINT(4 байта) с именем PIC размером высота * ширина картинки.
$tStruct = DllStructCreate("uint PIC[" & $iWidth * $iHeight & "]")
For $i = 0 To UBound($aPic) - 1
  DllStructSetData($tStruct, "PIC", $aPic[$i], $i + 1)
Next

; Создать картинку из структуры.
$hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB, $iWidth * 4, DllStructGetPtr($tStruct, "PIC"))

; Координаты центров пикселей находятся между целыми значениями.
_GDIPlus_GraphicsSetPixelOffsetMode($hBitmap, 2)

; Сохранить в файл.
_GDIPlus_ImageSaveToFile($hBitmap, "pic.bmp")

Local $hBitmap_Scaled = _GDIPlus_ImageResize($hBitmap, 320, 320, $GDIP_INTERPOLATIONMODE_NEARESTNEIGHBOR) ;resize image

; Сохранить в файл.
_GDIPlus_ImageSaveToFile($hBitmap_Scaled, "pic2.bmp")

; Удалить ресурсы GDI+.
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_ImageDispose($hBitmap_Scaled)
_GDIPlus_Shutdown()
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Ну я же написал:
добавить в функцию _GDIPlus_ImageResize строку
Нужно править саму функцию _GDIPlus_ImageResize или сделать собственную. Режим смещения пикселей устанавливается для Graphics, а не для Bitmap, и применяется в момент рисования на Graphics.
 
Автор
V

VadimKHL

Новичок
Сообщения
155
Репутация
0
Ааа, вот оно как.
Получается нужно растягивать уже сам Graphics?
А как можно поправить саму функцию _GDIPlus_ImageResize?
Где ее искать?
 
Автор
V

VadimKHL

Новичок
Сообщения
155
Репутация
0
Большое спасибо!
Разобрался, все работает!
Код:
#include <GDIPlus.au3>
_GDIPlus_Startup()

; Задать размер картинки.
Global $iWidth = 32, $iHeight = 32

; Массив содержащий данные картинки, заполненный случайным образом.
Global $aPic[$iWidth * $iHeight]
For $i = 0 To UBound($aPic) - 1
  $aPic[$i] = BitOR(0xFF000000, Random(0, 0xFFFFFF, 1))
Next

; Создать структуру UINT(4 байта) с именем PIC размером высота * ширина картинки.
$tStruct = DllStructCreate("uint PIC[" & $iWidth * $iHeight & "]")
For $i = 0 To UBound($aPic) - 1
  DllStructSetData($tStruct, "PIC", $aPic[$i], $i + 1)
Next

; Создать картинку из структуры.
$hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB, $iWidth * 4, DllStructGetPtr($tStruct, "PIC"))

; Сохранить в файл.
_GDIPlus_ImageSaveToFile($hBitmap, "pic.bmp")

Local $hBitmap_Scaled = _GDIPlus_ImageResizeNew($hBitmap, 320, 320, $GDIP_INTERPOLATIONMODE_NEARESTNEIGHBOR, 2) ;resize image

; Сохранить в файл.
_GDIPlus_ImageSaveToFile($hBitmap_Scaled, "pic2.bmp")

; Удалить ресурсы GDI+.
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_ImageDispose($hBitmap_Scaled)
_GDIPlus_Shutdown()

Func _GDIPlus_ImageResizeNew($hImage, $iNewWidth, $iNewHeight, $iInterpolationMode = $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC, $PixelOffsetMode = 0)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iNewWidth, $iNewHeight)
    If @error Then Return SetError(1, 0, 0)
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    If @error Then
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(2, @extended, 0)
    EndIf
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    If @error Then
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(3, @extended, 0)
    EndIf
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $PixelOffsetMode)
    If @error Then
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, @extended, 0)
    EndIf
    _GDIPlus_GraphicsDrawImageRect($hBmpCtxt, $hImage, 0, 0, $iNewWidth, $iNewHeight)
    If @error Then
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(5, @extended, 0)
    EndIf
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageResizeNew
 
Верх