Что нового

Изменнение размера картинки с сохранением пропорций

SECTOR

Продвинутый
Сообщения
398
Репутация
58
Привет всем. Знаю, что задача простая, но как изменить размер картинки с сохранением пропорций?
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1 575
Репутация
335
Тебе в виде кода или теорию? :smile:
Пока могу только объяснить теорию.
Допустим у тебя есть картинка 500х600. Тебе из нее нужно получить 200х(на сколько то там)
Делишь 500 на 200 (размер исходного изображения, на полученное) - получаешь коэффициент пропорциональности.
Ну а найти вторую сторону найти можно поделив 600 на этот коэффициент :smile:
 
Автор
SECTOR

SECTOR

Продвинутый
Сообщения
398
Репутация
58
Теория то ясна, но мозг уже кипит! Не могу построить алгоритм, который будет работать в любом случае (при любых размерах). Как нарисовать тоже известно, нужна помощь лишь в алгоритме!
 
Автор
SECTOR

SECTOR

Продвинутый
Сообщения
398
Репутация
58
FlatX007 сказал(а):
Дай что у тебя получилось ...
Вот совсем неправильный алгоритм: :smile:
Код:
#include <GDIPlus.au3>
#include <Math.au3>
#include <Misc.au3>

_ImageResize("Rus.bmp","Rus_2.bmp",800,300)

Func _ImageResize($sInImage, $sOutImage, $iW, $iH,$iARGB = 0xFFFFFFFF)

   Local $hWnd, $hDC, $hBMP, $hImage1, $hImage2, $hGraphic, $CLSID, $H, $W, $coff, $X = 0, $Y = 0

;OutFile extension , to use for the encoder later on.
    Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1))

    ; Win api to create blank bitmap at the width and height to put your resized image on.
    $hWnd = _WinAPI_GetDesktopWindow()
    $hDC = _WinAPI_GetDC($hWnd)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
    _WinAPI_ReleaseDC($hWnd, $hDC)

    ;Start GDIPlus
    _GDIPlus_Startup()

    ;Get the handle of blank bitmap you created above as an image
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP)

    ;Load the image you want to resize.
    $hImage2 = _GDIPlus_ImageLoadFromFile($sInImage)

    $W = _GDIPlus_ImageGetWidth($hImage2)
    $H = _GDIPlus_ImageGetHeight($hImage2)

	;Get the graphic context of the blank bitmap
    $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage1)

    ;Draw the loaded image onto the blank bitmap at the size you want
	_GDIPlus_GraphicsClear($hGraphic,$iARGB)

	$coff = _Iif($W>$H,(_Max($W,$iW)/_Min($W,$iW)),(_Max($H,$iH)/_Min($H,$iH)))

	$W = Execute($W&_Iif($iW>$W,"*","/")&$coff)
	$H = Execute($H&_Iif($iH<$H,"*","/")&$coff)


	MsgBox(0,"","coff="&$coff&@CRLF&"W="&$W&@CRLF&"H="&$H&@CRLF&"X="&$X&@CRLF&"Y="&$Y)
	_GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, $X, $Y, $W, $H)


    ;Get the encoder of to save the resized image in the format you want.
    $CLSID = _GDIPlus_EncodersGetCLSID($Ext)

    ;Save the new resized image.
    _GDIPlus_ImageSaveToFileEx($hImage1, $sOutImage, $CLSID)

    ;Clean up and shutdown GDIPlus.
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_ImageDispose($hImage2)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _WinAPI_DeleteObject($hBMP)
    _GDIPlus_Shutdown()
EndFunc


Более-менее рабочий скрипт уже не вспомню. :(
В итоге я хотел получить 4 переменные (W,H,X,Y) для функции _GDIPLus_GraphicsDrawImageRect
 

SyDr

Сидра
Сообщения
651
Репутация
158
Ты в своём примере приводишь изображение к указанному размеру. Независимо от того, какие размеры у первоначального изображения.
Надо:
1) Узнать размеры первоначального изображения.
2) Посчитать размеры нового изображения в зависомсти от того, что о нём известно (высота, ширина или коэффициент пропорциональности).
3) Сохранить изображение с новыми параметрами.

Код:
#include <GDIPlus.au3>
#include <Math.au3>
#include <Misc.au3>

_ImageResize("Rus.bmp","Rus_2.bmp", 800)

Func _ImageResize($sInImage, $sOutImage, $iNewWidth, $iARGB = 0xFFFFFFFF)
   Local $hWnd, $hDC, $hBMP, $hImage1, $hImage2, $hGraphic, $CLSID, $iOldWidth, $iOldHeight, $iNewHeight

	;OutFile extension , to use for the encoder later on.
    Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1))

	;Start GDIPlus

	_GDIPlus_Startup()

     ;Load the image you want to resize.
	$hImage2 = _GDIPlus_ImageLoadFromFile($sInImage)
    $iOldWidth = _GDIPlus_ImageGetWidth($hImage2)
    $iOldHeight = _GDIPlus_ImageGetHeight($hImage2)

	; $iNewWidth
	$iNewHeight = Round($iNewWidth/$iOldWidth * $iOldHeight)

    ; Win api to create blank bitmap at the width and height to put your resized image on.
    $hWnd = _WinAPI_GetDesktopWindow()
    $hDC = _WinAPI_GetDC($hWnd)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $iNewWidth, $iNewHeight)
    _WinAPI_ReleaseDC($hWnd, $hDC)

    ;Get the handle of blank bitmap you created above as an image
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP)

    ;Get the graphic context of the blank bitmap
    $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage1)

    ;Draw the loaded image onto the blank bitmap at the size you want
    _GDIPlus_GraphicsClear($hGraphic,$iARGB)
    _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $iNewWidth, $iNewHeight)

    ;Get the encoder of to save the resized image in the format you want.
    $CLSID = _GDIPlus_EncodersGetCLSID($Ext)

    ;Save the new resized image.
    _GDIPlus_ImageSaveToFileEx($hImage1, $sOutImage, $CLSID)

    ;Clean up and shutdown GDIPlus.
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_ImageDispose($hImage2)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _WinAPI_DeleteObject($hBMP)
    _GDIPlus_Shutdown()
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 712
SyDr, в твоем примере убьется вся прозрачность, если она конечно будет (.png и т. д.). Лучше использовать _GDIPlus_ImageGetThumbnail() из GDIP UDF.
 
Автор
SECTOR

SECTOR

Продвинутый
Сообщения
398
Репутация
58
SyDr, а почему в твоем примере нет параметра $iNewHeight?
Этот параметр обязателен :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 712
Самый простой пример (прозрачность сохраняется).

Код:
#Include <GDIPlus.au3>

$Max = 256

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile('Original.png')
$H = _GDIPlus_ImageGetHeight($hImage)
$W = _GDIPlus_ImageGetWidth($hImage)
If $W > $H Then
	$H = $Max / $W * $H
	$W = $Max
Else
	$W =$Max / $H * $W
	$H = $Max
EndIf
$hThumb = _GDIPlus_ImageGetThumbnail($hImage, $W, $H)
_GDIPlus_ImageSaveToFile($hThumb, 'Resized.png')
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hThumb)
_GDIPlus_Shutdown()

Func _GDIPlus_ImageGetThumbnail($hImage, $iWidth, $iHeight)

	Local $aResult = DllCall($ghGDIPDll, 'uint', 'GdipGetImageThumbnail', 'ptr', $hImage, 'uint', $iWidth, 'uint', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)

	If @error Then
		Return SetError(@error, @extended, 0)
	EndIf
	Return $aResult[4]
EndFunc   ;==>_GDIPlus_ImageGetThumbnail
 
  • Like
Реакции: Norm
Автор
SECTOR

SECTOR

Продвинутый
Сообщения
398
Репутация
58
Yashied сказал(а):
Самый простой пример (прозрачность сохраняется). ...
Работает! :ok:

Но я хотел, чтоб можно было указать ширину и высоту конечного риссунка;
чтоб был, допустим, белый фон, а по центру нужный рисунок :whistle:
 

SyDr

Сидра
Сообщения
651
Репутация
158
Yashied [?]
в твоем примере убьется вся прозрачность, если она конечно будет (.png и т. д.)
Это не мой пример :smile: Я просто разместил объяву модифицировал чуток код автора.

SECTOR [?]
SyDr, а почему в твоем примере нет параметра $iNewHeight?Этот параметр обязателен
Так и надо же писать сразу. Нельзя ведь преобразовать картинку 100x800 в 800x100 с сохранением пропорций.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 712
SECTOR сказал(а):
Но я хотел, чтоб можно было указать ширину и высоту конечного риссунка;
чтоб был, допустим, белый фон, а по центру нужный рисунок
Код:
#Include <GDIPlus.au3>
#Include <WinAPI.au3>

$Width = 256
$Height = 256

_GDIPlus_Startup()
$hOrigin = _GDIPlus_ImageLoadFromFile('Original.png')
$W = _GDIPlus_ImageGetWidth($hOrigin)
$H = _GDIPlus_ImageGetHeight($hOrigin)
$K1 = $Width / $W
$K2 = $Height / $H
If $K1 > $K2 Then
	$K1 = $K2
EndIf
$W *= $K1
$H *= $K1
$hBitmap = _WinAPI_CreateSolidBitmap(0, 0xFFFFFF, $Width, $Height)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hOrigin, ($Width - $W) / 2, ($Height - $H) / 2, $W, $H)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_ImageDispose($hOrigin)
_GDIPlus_ImageSaveToFile($hImage, 'Resized.png')
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
 
Автор
SECTOR

SECTOR

Продвинутый
Сообщения
398
Репутация
58
Yashied, СПАСИБО! :ok:

:IL_AutoIt_1: :IL_AutoIt_1: :IL_AutoIt_1:
 
Верх