Board logo

标题: [文件操作] [已解决]求批处理一批大小均不相同的图片,所有图片上下左右各切掉10% [打印本页]

作者: crownking1983    时间: 2020-2-13 03:49     标题: [已解决]求批处理一批大小均不相同的图片,所有图片上下左右各切掉10%

本帖最后由 crownking1983 于 2020-2-14 14:41 编辑

我这里有四千多张图片,尺寸大小有1920*1080的 有1600*900的 还有1200*900的 甚至还有1692*728这样异形的。

求批处理这一批大小均不相同的图片,所有图片上下左右各切掉10%

我在百度上问过这个问题,有一个好心的高手给我了一个方案。他使用批处理加mogrify.exe批处理命令是 "mogrify -crop +0+0 -crop -0-0 *.jpg" 将0写成上下左右要分别残切的像素数值就可以了

但是他这个批处理命令是批量去掉文件夹内所有图片的指定像素 左X像素上X像素右X像素下X像素 可以实现统一尺寸图片的批处理 但是我的这几千张图不是统一尺寸的 所以到这里跪求高人给一个能所有图片自动按每张图比例的上下左右各切掉10%的批处理方案

跪求了 大神们!
作者: went    时间: 2020-2-13 16:17

本帖最后由 went 于 2020-2-13 16:25 编辑
  1. function cutImg {
  2.     param (
  3.         [parameter(Mandatory=$true)]$src,
  4.         $top=0,$bottom=0,$left=0,$rigth=0
  5.     )
  6.     if(Test-Path -LiteralPath $src){$srcFile=[System.IO.FileInfo]::new($src)}else{Write-Host "路径错误";return}
  7.     if(($top -lt 0) -or ($bottom -lt 0) -or ($left -lt 0) -or ($rigth -lt 0)){Write-Host "参数小于零";return}
  8.     if(($top+$bottom) -ge 100){Write-Host "高为零";return}
  9.     if(($left+$right) -ge 100){Write-Host "款为零";return}
  10.     $srcBmp=[System.Drawing.Bitmap]::FromFile($src) #源图片
  11.     [int]$tagWidth=$srcBmp.Width*(1-$top/100-$bottom/100)
  12.     [int]$tagHeight=$srcBmp.Height*(1-$left/100-$rigth/100)
  13.     $srcRect=[System.Drawing.Rectangle]::new($srcBmp.Width*($left/100),$srcBmp.Height*($top/100),$tagWidth,$tagHeight) #源裁剪矩形
  14.     $tagRect=[System.Drawing.Rectangle]::new(0,0,$tagWidth,$tagHeight) #目标矩形
  15.     $tagBmp=[System.Drawing.Bitmap]::new($tagWidth,$tagHeight) #目标图片
  16.     $g=[System.Drawing.Graphics]::FromImage($tagBmp) #画笔
  17.     $g.DrawImage($srcBmp,$tagRect,$srcRect,[System.Drawing.GraphicsUnit]::Pixel)
  18.     $tagBmp.Save(($srcFile.DirectoryName+"\"+$srcFile.BaseName+"_cut"+$srcFile.Extension),[System.Drawing.Imaging.ImageFormat]::Jpeg)
  19.     $srcBmp.Dispose()
  20.     $tagBmp.Dispose()
  21.     Write-Host ($src+"`t处理完成!")
  22. }
  23. [void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
  24. dir -Filter "*.jpg" -File | foreach {cutImg -src ($_.FullName) -top 10 -bottom 10 -left 10 -rigth 10}
  25. pause
复制代码
保存ps1文件,放到jpg文件目录下右键运行
记得先测试一下
作者: crownking1983    时间: 2020-2-13 17:05

回复 2# went


    啊大神,恕我愚笨,这个不是bat批处理命令对吗?保存为ps1文件后,需要安装什么软件来运行吗?
作者: crownking1983    时间: 2020-2-13 17:06

回复 2# went


    另外还有,能否放到文件夹外面运行 因为这几千个文件在不同的文件夹里 处理完以后还得放回原文件夹 不然网站里的引用链接就都完了
作者: went    时间: 2020-2-13 17:58

回复 3# crownking1983


    你电脑上有powershell吗
作者: went    时间: 2020-2-13 18:32

本帖最后由 went 于 2020-2-14 14:01 编辑
  1. @echo off
  2. powershell -version 2.0 -c ("&{Get-Content '%~0' | Select-Object -Skip 3 | Out-String | Invoke-Expression}")
  3. pause&exit
  4. function cutImg {
  5.     param (
  6.         [parameter(Mandatory=$true)]$srcFile, #源图片
  7.         $top=0,$bottom=0,$left=0,$rigth=0 #裁剪百分比: 上 下 左 右
  8.     )
  9.     if(($top -lt 0) -or ($bottom -lt 0) -or ($left -lt 0) -or ($rigth -lt 0)){Write-Host "参数小于零";return}
  10.     if(($top+$bottom) -ge 100){Write-Host "高为零";return}
  11.     if(($left+$right) -ge 100){Write-Host "款为零";return}
  12.     $srcBmp=[System.Drawing.Bitmap]::FromFile($srcFile.FullName) #源图片
  13.     [int]$tagWidth=$srcBmp.Width*(1-$left/100-$rigth/100)
  14.     [int]$tagHeight=$srcBmp.Height*(1-$top/100-$bottom/100)
  15.     $srcRect=[System.Drawing.Rectangle]::FromLTRB($srcBmp.Width*($left/100),$srcBmp.Height*($top/100),$tagWidth+$srcBmp.Width*($left/100),$tagHeight+$srcBmp.Height*($top/100)) #源裁剪矩形
  16.     $tagRect=[System.Drawing.Rectangle]::FromLTRB(0,0,$tagWidth,$tagHeight) #目标矩形
  17.     $tagBmp=New-Object "System.Drawing.Bitmap" -ArgumentList @($tagWidth,$tagHeight) #目标图片
  18.     [System.Drawing.Graphics]$g=[System.Drawing.Graphics]::FromImage($tagBmp) #画笔
  19.     $g.DrawImage($srcBmp,$tagRect,$srcRect,[System.Drawing.GraphicsUnit]::Pixel)
  20.     $tagBmp.Save(($srcFile.DirectoryName+"\"+$srcFile.BaseName+"_cut"+$srcFile.Extension),[System.Drawing.Imaging.ImageFormat]::Jpeg)
  21.     $srcBmp.Dispose()
  22.     $tagBmp.Dispose()
  23.     [System.GC]::Collect(0,[System.GCCollectionMode]::Forced) #释放资源
  24.     Write-Host ($srcFile.FullName+"`t处理完成!")
  25.     Start-Sleep -Milliseconds 10
  26. }
  27. [void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
  28. dir -Path . -Filter "*.jpg" -Recurse | foreach {cutImg -srcFile $_ -top 10 -bottom 10 -left 10 -rigth 10}
复制代码
改了下,存为bat文件运行,生成的图片在图片文件夹下,名称有个cut
作者: crownking1983    时间: 2020-2-13 23:07

回复 6# went


你好大神 我使用了 提示这样的错误 然后使用后也无任何变化 请问是哪里出错了呢?
作者: went    时间: 2020-2-13 23:39

回复 7# crownking1983


    编辑,另存为ansi编码,试试
作者: crownking1983    时间: 2020-2-14 00:56

回复 8# went


你好大神 我已经保存为ANSI编码形式 运行后也是不行的 和前面的问题相同一模一样 我是不是电脑里少安装了什么软件
作者: went    时间: 2020-2-14 01:05

本帖最后由 went 于 2020-2-14 01:12 编辑

回复 9# crownking1983


    改了点,你运行后截图看看提示什么
可能你powershell版本太低了
作者: crownking1983    时间: 2020-2-14 01:24

回复 10# went


大神 你说的没错 我的版本是2.0的 可能的确是版本低了 我明天起床下载个5.1版本的吧 谢谢你啊
作者: crownking1983    时间: 2020-2-14 02:28

回复 10# went


    大神 升级了之后 现在运行提示的是以下内容了。而且 必须要在与图片同级目录下运行。
方法调用失败,因为 [System.IO.FileInfo] 不包含名为“new”的方法。
所在位置 行:6 字符: 71
+     if(Test-Path -LiteralPath $src){$srcFile=[System.IO.FileInfo]::new <<<< (
$src)}else{Write-Host "路径错误";return}
    + CategoryInfo          : InvalidOperation: (new:String) [], RuntimeExcept
   ion
    + FullyQualifiedErrorId : MethodNotFound

方法调用失败,因为 [System.Drawing.Rectangle] 不包含名为“new”的方法。
所在位置 行:13 字符: 45
+     $srcRect=[System.Drawing.Rectangle]::new <<<< ($srcBmp.Width*($left/100),
$srcBmp.Height*($top/100),$tagWidth,$tagHeight) #源裁剪矩形
    + CategoryInfo          : InvalidOperation: (new:String) [], RuntimeExcept
   ion
    + FullyQualifiedErrorId : MethodNotFound

方法调用失败,因为 [System.Drawing.Rectangle] 不包含名为“new”的方法。
所在位置 行:14 字符: 45
+     $tagRect=[System.Drawing.Rectangle]::new <<<< (0,0,$tagWidth,$tagHeight)
#目标矩形
    + CategoryInfo          : InvalidOperation: (new:String) [], RuntimeExcept
   ion
    + FullyQualifiedErrorId : MethodNotFound

方法调用失败,因为 [System.Drawing.Bitmap] 不包含名为“new”的方法。
所在位置 行:15 字符: 41
+     $tagBmp=[System.Drawing.Bitmap]::new <<<< ($tagWidth,$tagHeight) #目标图

    + CategoryInfo          : InvalidOperation: (new:String) [], RuntimeExcept
   ion
    + FullyQualifiedErrorId : MethodNotFound

使用“1”个参数调用“FromImage”时发生异常:“值不能为空。
参数名: image”
所在位置 行:16 字符: 44
+     $g=[System.Drawing.Graphics]::FromImage <<<< ($tagBmp) #画笔
    + CategoryInfo          : NotSpecified: ( [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

不能对值为空的表达式调用方法。
所在位置 行:17 字符: 17
+     $g.DrawImage <<<< ($srcBmp,$tagRect,$srcRect,[System.Drawing.GraphicsUnit
]:ixel)
    + CategoryInfo          : InvalidOperation: (DrawImage:String) [], Runtime
   Exception
    + FullyQualifiedErrorId : InvokeMethodOnNull

不能对值为空的表达式调用方法。
所在位置 行:18 字符: 17
+     $tagBmp.Save <<<< (($srcFile.DirectoryName+"\"+$srcFile.BaseName+"_cut"+$
srcFile.Extension),[System.Drawing.Imaging.ImageFormat]::Jpeg)
    + CategoryInfo          : InvalidOperation: (Save:String) [], RuntimeExcep
   tion
    + FullyQualifiedErrorId : InvokeMethodOnNull

不能对值为空的表达式调用方法。
所在位置 行:20 字符: 20
+     $tagBmp.Dispose <<<< ()
    + CategoryInfo          : InvalidOperation: (Dispose:String) [], RuntimeEx
   ception
    + FullyQualifiedErrorId : InvokeMethodOnNull

D:\0.系统文档桌面\桌面\新建文件夹 (4)\1\0003.jpg        处理完成!
请按任意键继续. . .
作者: crownking1983    时间: 2020-2-14 02:29

大神 升级了之后 现在运行提示的是上面的内容了。而且 必须要在与图片同级目录下运行。放在文件夹外面运行的话,运行后直接就关闭了。
作者: flashercs    时间: 2020-2-14 03:44

本帖最后由 flashercs 于 2020-2-14 04:09 编辑

保存为 "图片剪裁.bat",能处理当前目录和所有子目录中的图片,直接覆盖原图. 先测试.
  1. ' &cls&@cscript -nologo -e:vbscript "%~f0" "%~dp0" & pause & exit /b
  2. ' 脚本功能:剪裁图片-Crop Image, 四周剪裁10%,并覆盖源文件
  3. ' 用法:script.vbs file1 file2 ... folder1 folder2 ...
  4. Option Explicit
  5. On Error Resume Next
  6. If WScript.Arguments.Count = 0 Then
  7.   WScript.Echo "参数个数不能为0"
  8.   WScript.Quit 1
  9. End If
  10. Const conIMAGETYPES = "|jpg|jpeg|png|bmp|tiff|gif|" ' 图片类型列表
  11. Const conRECURSE = True ' 是否遍历子目录
  12. Dim fso
  13. Set fso = CreateObject("Scripting.FileSystemObject")
  14. With CreateObject("WScript.Shell")
  15.   .CurrentDirectory = fso.GetParentFolderName(WScript.ScriptFullName)
  16. End With
  17. Dim Img 'As ImageFile
  18. Dim IP 'As ImageProcess
  19. Set Img = CreateObject("WIA.ImageFile")
  20. Set IP = CreateObject("WIA.ImageProcess")
  21. IP.Filters.Add IP.FilterInfos("Crop").FilterID
  22. ShowError
  23. Dim i,strArgi
  24. For i = 0 To WScript.Arguments.Count - 1
  25.   strArgi = WScript.Arguments(i)
  26.   If fso.FileExists(strArgi) Then
  27.     GenFile fso.GetFile(strArgi)
  28.   ElseIf fso.FolderExists(strArgi) Then
  29.     GenFolder fso.GetFolder(strArgi)
  30.   Else
  31.     WScript.Echo "找不到文件或目录:" & strArgi
  32.   End If
  33. Next
  34. ShowError
  35. Set fso = Nothing
  36. Set Img = Nothing
  37. Set IP = Nothing
  38. WScript.Quit 0
  39. ' Sub functions
  40. Sub GenFile(objFile)
  41.   On Error Resume Next
  42.   If InStr(1,conIMAGETYPES,"|" & fso.GetExtensionName(objFile.Name) & "|",vbTextCompare) Then
  43.     WScript.Echo "处理图片:" & objFile.Path
  44.     CropImage objFile.Path,objFile.Path
  45.   Else
  46.    ' WScript.Echo "未处理图片:" & objFile.Path
  47.   End If
  48.   ShowError
  49. End Sub
  50. Sub GenFolder(objFolder)
  51.   On Error Resume Next
  52.   Dim objFile,objSubFolder
  53.   ' WScript.Echo "处理目录:" & objFolder.Path
  54.   For Each objFile In objFolder.Files
  55.     GenFile objFile
  56.   Next
  57.   If conRECURSE Then
  58.     For Each objSubFolder In objFolder.SubFolders
  59.       GenFolder objSubFolder
  60.     Next
  61.   End If
  62.   ShowError
  63. End Sub
  64. Sub CropImage(strImageSrc,strImageDst)
  65.   On Error Resume Next
  66.   Img.LoadFile strImageSrc
  67.   IP.Filters(1).Properties("Left") = Img.Width \ 10
  68.   IP.Filters(1).Properties("Top") = Img.Height \ 10
  69.   IP.Filters(1).Properties("Right") = Img.Width \ 10
  70.   IP.Filters(1).Properties("Bottom") = Img.Height \ 10
  71.   Set Img = IP.Apply(Img)
  72.   If fso.FileExists(strImageDst) Then
  73.     fso.DeleteFile strImageDst,True
  74.   End If
  75.   Img.SaveFile strImageDst
  76.   ShowError
  77. End Sub
  78. Sub ShowError()
  79.   If Err.Number <> 0 Then
  80.     WScript.Echo "Err # " & Err.Number & vbNewLine & _
  81.     "Description: " & Err.Description & vbnewline & _
  82.     "Source: " & Err.Source
  83.     Err.Clear
  84.   End If
  85. End Sub
复制代码

作者: went    时间: 2020-2-14 11:56

回复 13# crownking1983


    给你改成支持2.0的了,记得用ansi保存
作者: crownking1983    时间: 2020-2-14 14:38

回复 15# went


    太谢谢你了 大神 大神啊!!!
作者: flashercs    时间: 2020-2-14 14:54

本帖最后由 flashercs 于 2020-2-14 14:59 编辑

回复 6# went

用GDI处理图片要建议:
    1.新图片的dpi最好保持与原图片一致,比如原图是350dpi,新图也要是350dpi,而Graphics画出默认是96dpi
2.新图片jpeg的压缩率要保持与原图片一致或接近.而jpeg默认保存的压缩率是50%
作者: went    时间: 2020-2-14 15:35

回复 18# flashercs


    用过其他格式,发现生成文件太大,翻了几倍




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2