Что нового

[Математика] Сложная задача по масштабированию картинок.

vaf

Новичок
Сообщения
190
Репутация
2
Добрый вечер / день уважаемые форумчане.
Возникла следующая задача:
Дана определенная ширина - ну скажем 1024 точки.
и дано разное количество картинок, разного размера.

необходимо все их выравнять по высоте, но чтобы из общая длина была равна этим самым к примеру 1024 точкам, т.е. выровнять все картинки по высоте, расположив их в один ряд, т.е. необходимо подобрать общую для всех высоту картинок, чтобы их общая ширина длине была равна определенному значению. (нужно это для красивого отображения картинок в один ряд)

пока сделал по колхозному. взял общую ширину и разделил на количество картинок, получился забор :smile: т.к. их высота получилась разная.
Вопрос - как рассчитать эту высоту ?
С ходу пришла только одна идея. Сделать цикл скажем от 1 и до общей ширины.
в цикле менять высоту всех картинок и смотреть какая получается общая ширина, но это не математика, это подгон. В принципе меня бы устроило, все осложняется тем, что я не знаю каким образом масштабировать картинки в autoit
Если кто нибудь напишет функцию, буду очень премного благодарен, да и думаю что наработки будут полезны и другим.
функция скажем

Код:
func resize ($width, $dim[$n],)

где $width - общая ширина, $dim[$n] - массив из $n картинок, а на выходе функции была бы высота для всех этих картинок.

Помогите пожалуйста :-[
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
Держи функцию:
Код:
#Include <GDIPlus.au3>

;$hImage - путь к рисунку
;hLocation - путь куда сохранить рисунок
;$iWidth - задать ширину
;$iHeight - задать высоту

Func _GDIPlus_ImageResize($hImage, $hLocation, $iWidth=@DesktopWidth, $iHeight=@DesktopHeight)
	Local $iExt = '.' & StringRegExpReplace($hImage, '.*\.(\S+)', '\1')
	_GDIPlus_Startup()
	$hImage = _GDIPlus_ImageLoadFromFile($hImage)
    Local $aResult = DllCall($ghGDIPDll, 'uint', 'GdipGetImageThumbnail', 'ptr', $hImage, 'uint', $iWidth, 'uint', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)
    _GDIPlus_ImageSaveToFile($aResult[4], $hLocation)
	_GDIPlus_ImageDispose($hImage)
	_GDIPlus_Shutdown()
EndFunc


И возможно тебе понадобится узнать изначальные размеры картинок:
Код:
;Возвращает массив и шириной и высотой уартинке

Func _GDIPlus_GetImageSize($h_img)
   _GDIPlus_Startup()
   $hImg = _GDIPlus_ImageLoadFromFile($h_img)
   $Arr = _GDIPlus_ImageGetWidth($hImg) & '|' & _GDIPlus_ImageGetHeight($hImg)
   $ImgSize = StringSplit($Arr, '|')
   Return $ImgSize
   _GDIPlus_Shutdown()
EndFunc
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
Держи функцию:
Вот как раз с ней и сижу, вот в идеале было бы не сохранять рисунок, а просто узнать новую ширину в зависимости от заданной нами высоты.
точнее правильнее было бы так задать вопрос. Вот мы получили ширину и высоту картинки.
Нужно составить такую функцию, которая бы возвращала ширину картинки от заданной высоты, в этой функции нужно как то задать формулу масштабирования.
допустим мы получили ширину картинки 628px высоту 280px. Какова будет ширина картинки, если ее высота будет скажем 100px ? вот эту формулу бы.
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Код:
#Include <GDIPlus.au3>
#Include <WinAPIEx.au3>

$hForm = GUICreate('', 500, 500)
$iPic0 = GUICtrlCreatePic('', 0, 0, 500, 100)
$iPic1 = GUICtrlCreatePic('', 0, 100, 500, 100)
$iPic2 = GUICtrlCreatePic('', 0, 200, 500, 100)
$iPic3 = GUICtrlCreatePic('', 0, 300, 500, 100)
$iPic4 = GUICtrlCreatePic('', 0, 400, 500, 100)
GUISetState()

_GDIPlus_Startup()
For $i = 0 To 4
  $hImage =  _GDIPlus_ImageLoadFromFile(@ScriptDir & '\' & $i & '.jpg')
  $hThumb = _GDIPlus_GetImageThumbnail($hImage, ((_GDIPlus_ImageGetWidth($hImage) * 100) / _GDIPlus_ImageGetHeight($hImage)), 100)
  $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hThumb)
  _SendMessage(GUICtrlGetHandle(Eval('iPic' & $i)), 0x0172, 0, $hBitmap)
  _WinAPI_DeleteObject($hBitmap)
  _GDIPlus_ImageDispose($hImage)
  _GDIPlus_ImageDispose($hThumb)
Next
_GDIPlus_Shutdown()

While 1
	Switch GUIGetMsg()
		Case -3
			Exit
	EndSwitch
Wend

Func _GDIPlus_GetImageThumbnail($hImage, $iWidth, $iHeight)
    Local $Ret = DllCall($ghGDIPDll, 'int', 'GdipGetImageThumbnail', 'ptr', $hImage, 'int', $iWidth, 'int', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)
    If (@error) Or ($Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[4]
EndFunc


В архиве пример с картинками.

А формула такая:

OW - Ширина картинки
OH - Высота картинки
NH - новая высота картинки

((OW * NH) / OH) - получим новую ширину.

Когда - то тоже задался этим вопросом, мне подсказал Yashied, за что ему огромное спасибо.
 

AZJIO

Меценат
Меценат
Сообщения
2,891
Репутация
1,195
vaf
vaf сказал(а):
допустим мы получили ширину картинки 628px высоту 280px. Какова будет ширина картинки, если ее высота будет скажем 100px ? вот эту формулу бы.
Это слишком просто. (пропорции, где то 5 класс)
Код:
MsgBox(0, 'Сообщение', $h1)

Func _GetWidth($w1, $h1, $h2)
	Return Round($w1*$h2/$h1)
EndFunc


А вот функция, когда требуется картинку уложить в квадрат с заданными размерами.
Код:
#include <Array.au3>

$aWH=_Coor(370, 250, 1280, 1024) ; возвращает пропорциональные координаты по наименьшему
_ArrayDisplay($aWH, 'aWH')

; $w1, $h1 - размер квадрата в который картинка должна поместитьcя
; $w2, $h2 - реальный размер картинки
Func _Coor($w1, $h1, $w2, $h2)
	Local $aXY[2] = [0,0], $kX=$w1/$w2, $kY=$h1/$h2
	If $kX>$kY Then
		$aXY[0]=Round($w2*$kY)
		$aXY[1]=$h1
	Else
		$aXY[0]=$w1
		$aXY[1]=Round($h2*$kX)
	EndIf
	Return $aXY
EndFunc
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
Я с Вашей помощью сделал вот так (см. ниже), но проблема в том, что не всегда срабатывает условие If $tmp >= $width Then ExitLoop. Хотя почему, понять не могу. Иногда срабатывает иногда нет.

Код:
$post_text = FileReadLine ($file)
$1 = _StringBetween($post_text,'title="','" src') ; Заносим в массив имена всех картинок

_GDIPlus_Startup()

   For $y = 1 To 250
	  $tmp = 0
	  For $i = 0 To UBound ($1) - 1
		 $xx = X ($path & $1[$i])
		 $yy = Y ($path & $1[$i])
		 $nx = Floor (resize ($xx, $yy, $y))
		 $tmp = $tmp + $nx
		 ;MsgBox (4096, $tmp, $nx & "=" & $1[$i] & " " & $xx & "x" & $yy & " , " & $y)
 	  Next
	  If $tmp >= $width Then ExitLoop ; Достигли нужной ширины, выходим из цикла. $y = высота картинок
   Next

Func resize ($ow, $oh, $nh)
   $x = (($ow * $nh) / $oh)
   Return $x
EndFunc

Func X ($sFileName)
   $id = _GDIPlus_ImageLoadFromFile($sFileName)
   $w  = _GDIPlus_ImageGetWidth ($id)
   Return $w
EndFunc

Func Y ($sFileName)
   $id = _GDIPlus_ImageLoadFromFile($sFileName)
   $h  = _GDIPlus_ImageGetHeight ($id)
   Return $h
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
vaf,
Предупреждение За нарушение правил форума (пункт В.11):
Любые отрывки AutoIt кода необходимо заключать в тег [autoit]
autoit.gif
(подробнее), а обычный код соответственно в тег [code]
code.gif
(подробнее). Также большие выдержки текста помещайте под тег [spoiler]
spoiler.gif
(подробнее), там где это поддерживается естественно. Как в случае с названием темы, также короткое и эргономичное сообщение привлекает больше внимания, и шансы на получение конкретного ответа увеличиваются.


С уважением, ваш Модератор.
 
Верх