Что нового

Разрезать картинку с числами на части

QQruza

Новичок
Сообщения
26
Репутация
0

pics.vsego.ru

Версия AutoIt: 3.3.8.1

Слева примеры картинок, которые нужно будет резать. Обратите внимание, что по горизонтали позиционирование чисел разное и то, что это только примеры, на практике эти картинки более разнообразны.
Разрезать нужно так, чтобы в одной части был один символ, и ширина новой картинки была равна ширине символа, т.е. пустой фон будет отрезан.
Результат - полученные отельные символы записываются в файл. Все преобразования картинки должны происходить без потери качества, можно в bmp.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Возможный вариант, обрезает по ширине:
Нужна GDIP UDF http://autoit-script.ru/index.php?topic=1384.0

Код:
#include <GDIP.au3>
#include <Array.au3>
#include <Color.au3>

$sImage = @ScriptDir & '\test.bmp'

Dim $a[1]
Dim $a2[1]
Dim $a3[1]

$Len = 5 ; 5-10

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile($sImage)
$iWidth = _GDIPlus_ImageGetWidth($hImage)
$iHeight = _GDIPlus_ImageGetHeight($hImage)
$iBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($iBitmap)

$color1 = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, 1, 1), 6) ; получаем цвет фона

If _ColorIsDarkShade($color1, 0) = 'True' Then
    $j = 10 ; от 0 до 240
Else
    $j = 200 ; от 0 до 240
EndIf

Dim $iMatrix[$iHeight]

For $W = 0 To $iWidth - 1
    For $H = 0 To $iHeight - 1

        $color2 = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $W + 1, $H), 6)

        If Abs(_ColorGetBlue($color1) - _ColorGetBlue($color2)) < $j Or Abs(_ColorGetRed($color1) - _ColorGetRed($color2)) < $j _
                Or Abs(_ColorGetGreen($color1) - _ColorGetGreen($color2)) < $j Then
            $iMatrix[$H] = 1
        Else
            $iMatrix[$H] = ''
        EndIf
    Next
    If Execute(_ArrayToString($iMatrix, '+')) < $iHeight Then _ArrayAdd($a, $W)
Next

For $s = 1 To UBound($a) - 1
    If $a[$s] - $a[$s - 1] >= $Len Then
        $a[$s] = $a[$s] & '#'
        $a[$s - 1] = $a[$s - 1] & '$'
    EndIf
Next
_ArrayDelete($a, UBound($a) - 1)
_ArrayDelete($a, 0)

For $s = 0 To UBound($a) - 1
    If StringInStr($a[$s], '#') > 0 And StringInStr($a[$s], '$') = 0 Then _ArrayAdd($a2, $a[$s])
    If StringInStr($a[$s], '$') > 0 And StringInStr($a[$s], '#') = 0 Then _ArrayAdd($a3, $a[$s])
Next
_ArrayTrim($a2, 1, 1)
_ArrayTrim($a3, 1, 1)

_GDIPlus_ImageDispose($hImage)
_WinAPI_DeleteObject($iBitmap)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()

For $s = 1 To UBound($a3) - 1
    _BitmapResize($sImage, $a2[$s] + 1, $a3[$s], $a3[$s] - $a2[$s], $iHeight, $s)
Next

Func _BitmapResize($Path, $x, $y, $x_Width, $y_Height, $i)
    _GDIPlus_Startup()
    $hSource = _GDIPlus_ImageLoadFromFile($Path)
    $hDestination = _GDIPlus_CreateBitmapFromScan0($x_Width, $y_Height, 0, _GDIPlus_GetImagePixelFormat($hSource))
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hDestination)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hSource, -$x, 0, $iWidth, $iHeight)
    _GDIPlus_ImageSaveToFile($hDestination, @ScriptDir & '\' & $i & '.bmp')
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_ImageDispose($hDestination)
    _GDIPlus_ImageDispose($hSource)
    _GDIPlus_Shutdown()
EndFunc   ;==>_BitmapResize

Func _GDIPlus_CreateBitmapFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $iWidth, 'int', $iHeight, 'int', $iStride, 'int', $iPixelFormat, 'ptr', $pScan0, 'ptr*', 0)
    If(@error) Or($Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[6]
EndFunc   ;==>_GDIPlus_CreateBitmapFromScan0

Func _GDIPlus_GetImagePixelFormat($hImage)
    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImagePixelFormat', 'ptr', $hImage, 'uint*', 0)
    If(@error) Or($Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[2]
EndFunc   ;==>_GDIPlus_GetImagePixelFormat

Func _ColorIsDarkShade($nColor, $iRetMode = 0)
    Local $i_Red = BitAND(BitShift($nColor, 16), 0xFF)
    Local $i_Green = BitAND(BitShift($nColor, 8), 0xFF)
    Local $i_Blue = BitAND($nColor, 0xFF)
    Local $iMidle_Color_Val = Int(765 / 2) ;765 is the total of 255 + 255 + 255
    If $iRetMode <> 0 Then
        If($i_Red + $i_Green + $i_Blue) < $iMidle_Color_Val Then
            Return "0xFFFFFF"
        Else
            Return "0x000000"
        EndIf
    EndIf
    Return($i_Red + $i_Green + $i_Blue) < $iMidle_Color_Val
EndFunc   ;==>_ColorIsDarkShade
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Интересно все-таки, работает код? :whistle:
 
Автор
Q

QQruza

Новичок
Сообщения
26
Репутация
0
Результат работы скрипта

Взял


Получил
Один файл



Взял

pics.vsego.ru

На выходе ничего нет

(файлы были из bmp в jpg для заливки на хостинг)

К сожалению скрипт задачу не выполняет
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
А эти картинки действительно такие маленькие?
Я настраивал на гораздо больших...
Тогда в 11 строке можно попробовать сделать $Len = 2 или $Len = 3
Скопировал картинки из предыдущего поста:
В архиве что получилось при $Len = 2, режет :laugh:
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
У меня создаётся такое впечатление, что я ппц какой умный...
:stars: :beer:
Код:
#include <GDIP.au3>
#include <Color.au3>

$sImage = @ScriptDir & '\1367.bmp'

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile($sImage)
Global $iWidth = _GDIPlus_ImageGetWidth($hImage)
Global $iHeight = _GDIPlus_ImageGetHeight($hImage)
$iBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($iBitmap)

$xLeft = 0
$xRight = 0
$x = 0

While $x < $iWidth-1
	While _BlackLine($x) And $x < $iWidth-1
		$x += 1
	WEnd
	$xLeft = $x
	While Not _BlackLine($x) And $x < $iWidth
		$x += 1
	WEnd
	$xRight = $x-1

	$hClone = _GDIPlus_BitmapCloneArea ($hBitmap, $xLeft, 0, $xRight-$xLeft, $iHeight, $GDIP_PXF24RGB)
    _GDIPlus_ImageSaveToFile ($hClone, @ScriptDir & "\Image_"&$xLeft&"_"&$xRight&".bmp")
    _GDIPlus_ImageDispose ($hClone)
WEnd

_GDIPlus_ImageDispose($hImage)
_WinAPI_DeleteObject($iBitmap)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()

Func _BlackLine($stolb)
	Local $color
	For $i = 0 To $iHeight-1
		$color = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap,$stolb,$i), 6)
		 If _ColorGetRed($color) > 100 Or _ColorGetGreen($color) > 100 Or _ColorGetBlue($color) > 100 Then Return False
	Next
	Return True
EndFunc
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
C2H5OH
А там ничего настроить нельзя, а то что-то мои тестовые картинки (в архиве) не режет ;)
 
Автор
Q

QQruza

Новичок
Сообщения
26
Репутация
0
C2H5OH, у меня твой скрипт выдает

Код:
pic crop2.au3 (43) : ==> "Func" statement has no matching "EndFunc".:

и результатов нет, проверял на твоих картинках

WSWR, поменял $Len = 2, картинку режет на 1,3,6
7 -нету, возможно из-за шума
Картинки именно такие маленькие, расстояние между цифрами 1-2 пикселя.

А возможно сделать так, чтобы шум в jpg тоже определялся как фон? Т.е. только небольшое отклонение от чистого фона тоже считалось фоном.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
QQruza,
это ты скопировал скрипт без последней строки.

WSWR,
все тестовые картинки ТС имели чёрный форн, а твои цветные, потому и не хавал.
Добавил, как у тебя, учет цвета фона с допустимым отклонением.
Код:
#include <GDIP.au3>
#include <Color.au3>

Global $delta = 10	; допустимое отклонение цвета фона от образца
$sImage = @ScriptDir & '\test1.bmp'

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile($sImage)
Global $iWidth = _GDIPlus_ImageGetWidth($hImage)
Global $iHeight = _GDIPlus_ImageGetHeight($hImage)
$iBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($iBitmap)

Global $Ground = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, 1, 1), 6) ; получаем образец цвета фона

$xLeft = 0
$xRight = 0
$x = 0

While $x < $iWidth-1
	While _BlackLine($x) And $x < $iWidth-1
		$x += 1
	WEnd
	$xLeft = $x
	While Not _BlackLine($x) And $x < $iWidth
		$x += 1
	WEnd
	$xRight = $x-1

	$hClone = _GDIPlus_BitmapCloneArea ($hBitmap, $xLeft, 0, $xRight-$xLeft, $iHeight, $GDIP_PXF24RGB)
    _GDIPlus_ImageSaveToFile ($hClone, @ScriptDir & "\Image_"&$xLeft&"_"&$xRight&".bmp")
    _GDIPlus_ImageDispose ($hClone)
WEnd

_GDIPlus_ImageDispose($hImage)
_WinAPI_DeleteObject($iBitmap)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()

Func _BlackLine($stolb)
	Local $color
	For $i = 0 To $iHeight-1
		$color = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap,$stolb,$i), 6)
		If Abs(_ColorGetRed($color)-_ColorGetRed($Ground)) > $delta Or _
		   Abs(_ColorGetGreen($color)-_ColorGetGreen($Ground)) > $delta Or _
		   Abs(_ColorGetBlue($color)-_ColorGetBlue($Ground)) > $delta Then Return False
	Next
	Return True
EndFunc
 
Верх