Что нового

Обрезка белого цвета на фотографиях - по верхней и нижней стороне

Пост номер 6 был отмечен как лучший ответ.

Snegovik

Чайник
Сообщения
41
Репутация
0
Здравствуйте, ребята.
Помогите обрезать фотографии.

Там в общем проблема такая.
Есть несколько фотографий jpg - в одной папке.
И у них надо убрать лишний белый цвет сверху и снизу, то есть укоротить эти jpg - по верхней и по нижней стороне.

Это можно как-то скриптом сделать ?
 

Вложения

ZaRaki

Новичок
Сообщения
48
Репутация
19
Здравствуйте, ребята.
Помогите обрезать фотографии.

Там в общем проблема такая.
Есть несколько фотографий jpg - в одной папке.
И у них надо убрать лишний белый цвет сверху и снизу, то есть укоротить эти jpg - по верхней и по нижней стороне.

Это можно как-то скриптом сделать ?
Такое сделать вполне реально, но вы должны понимать, что поскольку отображаемое может быть динамическим, то для скрипта нужно прописать алгоритм получения крайнего левого пикселя, правого, нижнего, верхнего - где заканчивается контент. Это всё 4 отдельных цикла, в итоге 1 файл может обрабатываться около 10 секунд.
 
Автор
S

Snegovik

Чайник
Сообщения
41
Репутация
0
Это всё 4 отдельных цикла, в итоге 1 файл может обрабатываться около 10 секунд.
Ничего страшного - лишь бы обрезал.
Сообщение автоматически объединено:

Насчет левых и правых пикселей - наверное не нужно, поскольку нужно обрезать только низ и верх.
 

ZaRaki

Новичок
Сообщения
48
Репутация
19
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <File.au3>
#include <ScreenCapture.au3>

Opt("PixelCoordMode", 2)

global $color = '000000'
global $mainimg = @ScriptDir & "\3.jpg"
global $itogimg = @ScriptDir & "\4.jpg"

   _GDIPlus_Startup()
   $hBitmap = _GDIPlus_BitmapCreateFromFile($mainimg)
   $img_w = _GDIPlus_ImageGetWidth($hBitmap)
   $img_y = _GDIPlus_ImageGetHeight($hBitmap)
   _GDIPlus_BitmapDispose($hBitmap)
   _GDIPlus_Shutdown()

   $gui_w = @desktopwidth-60
   $gui_y = @DesktopHeight-100
   $normalize_w = $img_w/$gui_w
   $normalize_y = $img_y/$gui_y
   if($img_y/$normalize_w < $gui_y) Then
      $total_w = $gui_w
      $total_y = $img_y/$normalize_w
   Else
      $total_w = $img_w/$normalize_y
      $total_y = $gui_y
   EndIf

   $hgui = GUICreate($mainimg, $total_w, $total_y, -1, -1, $WS_POPUP) ; Создаёт окно в центре экрана
   $hImage = GUICtrlCreatePic($mainimg, 0, 0, $total_w, $total_y)
   GUICtrlSetState(-1, $GUI_DISABLE)
   GUISetState()

WinWaitActive($hgui)
sleep(250)

            $pixel_left_top_coords = PixelSearch(0, 0, $total_w-1, $total_y-1,'0x' & $color,240,2,$hgui)
            if @error = 1 Then msgbox(0,"","что-то пошло не так")

            $pixel_right_bottom_coords = PixelSearch($total_w-1, $total_y-1, 0, 0,'0x' & $color,240,2,$hgui)
            if @error = 1 Then msgbox(0,"","что-то пошло не так")

            _ScreenCapture_CaptureWnd($itogimg, $hgui, 0, $pixel_left_top_coords[1]-3, $total_w-1, $pixel_right_bottom_coords[1]+3, False)

   GUIDelete()
 
Автор
S

Snegovik

Чайник
Сообщения
41
Репутация
0
Спасибо, скрипт делает обрезку.

Но есть два вопроса.
Как сделать эту обрезку - разом для всех файлов jpg, а не только для одного ?
И еще - у изначальной фотографии - ширина 680 пикселей, а у обработанной - ширина уже 750 пикселей.
Ширина же должна остаться неизменной, а получается - что она стала больше.
 

Tempo

Скриптер
Сообщения
495
Репутация
144
Можно так
Код:
#include <File.au3>
#include <GDIPlus.au3>

Local $sPath = FileSelectFolder("", @ScriptDir)
If @error Then Exit

Local $sMask = "*.jpg", $sPathOut = $sPath & "\Cropped", _
        $iColor = 0xFFFFFFFF, $iIndent = 5, $iQuality = 100

Local $aFiles = _FileListToArray($sPath, $sMask, $FLTA_FILES)
If @error Then Exit MsgBox($MB_TOPMOST + $MB_ICONERROR, Default, StringFormat('Файлы по шаблону не найдены -> "%s\%s"', $sPath, $sMask))

_GDIPlus_Startup()
If Not FileExists($sPathOut) Then DirCreate($sPathOut)
Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
Local $tParams = _GDIPlus_ParamInit(1)
Local $tData = DllStructCreate("int Quality")
DllStructSetData($tData, "Quality", $iQuality)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData))

Local $hBitmap, $iW, $iH, $tBitmapData, $iScan0, $tPixel, $iTop, $iBottom, $hBitmapCrop
For $i = 1 To $aFiles[0]
    $hBitmap = _GDIPlus_ImageLoadFromFile($sPath & "\" & $aFiles[$i])
    If @error Then
        MsgBox($MB_TOPMOST + $MB_ICONERROR, Default, StringFormat('Не удалось открыть изображение -> "%s\%s"', $sPath, $aFiles[$i]))
        ContinueLoop
    EndIf
    $iW = _GDIPlus_ImageGetWidth($hBitmap)
    $iH = _GDIPlus_ImageGetHeight($hBitmap)
    $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
    $iScan0 = DllStructGetData($tBitmapData, "Scan0")
    $tPixel = DllStructCreate("int[" & $iW * $iH & "]", $iScan0)
    $iTop = 0
    $iBottom = $iH
    For $iY = 0 To $iH - 1
        $iRowOffset = $iY * $iW + 1
        For $iX = 0 To $iW - 1
            $iPixel = DllStructGetData($tPixel, 1, $iRowOffset + $iX)
            If $iPixel <> $iColor Then
                $iTop = $iY
                ExitLoop 2
            EndIf
        Next
    Next
    For $iY = $iH - 1 To $iTop Step -1
        $iRowOffset = $iY * $iW + 1
        For $iX = 0 To $iW - 1
            $iPixel = DllStructGetData($tPixel, 1, $iRowOffset + $iX)
            If $iPixel <> $iColor Then
                $iBottom = $iY
                ExitLoop 2
            EndIf
        Next
    Next

    If $iTop - $iIndent >= 0 Then $iTop -= $iIndent
    If $iBottom + $iIndent <= $iH Then $iBottom += $iIndent
    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData)
    $hBitmapCrop = _GDIPlus_BitmapCloneArea($hBitmap, 0, $iTop, $iW, $iBottom - $iTop)
    _GDIPlus_ImageSaveToFileEx($hBitmapCrop, $sPathOut & "\" & $aFiles[$i], $sCLSID, $tParams)
    _GDIPlus_BitmapDispose($hBitmapCrop)
    _GDIPlus_BitmapDispose($hBitmap)
Next
_GDIPlus_Shutdown()
MsgBox($MB_TOPMOST + $MB_ICONINFORMATION, Default, "Обработка завершена")
ShellExecute($sPathOut)
 
Последнее редактирование:
Верх