AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77642075
Accepted
ElektroStudios
ElektroStudios
Asked: 2023-12-12 03:51:43 +0800 CST2023-12-12 03:51:43 +0800 CST 2023-12-12 03:51:43 +0800 CST

如何使用 ImageMagick 将图像正确居中以制作图标?

  • 772

在 Windows 下,使用 Batch-Script 或 Powershell 和ImageMagick,我只想创建一个适当的图标文件,就像您可以使用ToyCon或QuickAnyToIco程序创建的图标一样,即:

  • 图像层位于画布中央的图标
  • 它自动适应垂直或水平边缘,即图像自动缩小或放大。
  • 保持纵横比
  • 具有透明背景
  • 图标实际尺寸为 256x256px(图标内包含其他各种典型尺寸的任意图层:128x128、64x64、32x32、16x16 等)

这是一项简单的任务,任何用于 Windows 的传统图标转换器软件都可以完美完成。


现在,使用ImageMagick,icon:auto-resize参数 it 没有任何帮助,因为它拉伸图像以适应宽度和高度。

我读过ImageMagick 的文档,它有这两个修饰符:

  • '>' 标志:仅缩小较大的图像
  • '<' 标志:仅放大较小的图像

-resize我注意到它们可以在和参数中指定的宽度和高度值中指定-extent。

和这个:

  • '^':填充给定区域

……为了-extent论证。

但我找不到正确使用或组合它们的方法,通过缩小和放大(保留纵横比)自动适应宽度或高度来使图像居中。我坚持认为,就像QuickAnyToIco程序一样。


这是一个示例命令,我尝试为图标创建 256x256 png 图层:

输入图像尺寸:513x458

命令是这样的:

Magick.exe convert "image.jpg" -resize "256>x256" -background white -gravity center -extent "256^x256^" -quality 100 "output.png"

结果输出图像是这样的:

在此输入图像描述

输出正常!!,这与任何优秀的图标转换器软件产生的结果相同。

现在,使用相同的命令和图像大小为 208x242 的图像,我得到以下输出图像:

在此输入图像描述

输出错误!!图像居中,但顶部和底部边缘不合适。

我期望得到这个结果图像(由任何好的图标转换器软件生成):

在此输入图像描述

我可以使用这个命令来实现它:

Magick.exe convert "cover.jpg" -resize "256<x256" -background white -gravity center -extent "256^x256^" -quality 100 "output.png"

但它只适用于像这样的较小图像。同样的命令将生成另一个图像:

在此输入图像描述


笔记:

  • 白色背景只是一种方便的颜色,我选择它是为了更好地视觉呈现问题。

  • 上面示例中使用的原始输入图像:

    https://i.imgur.com/wiXntuD.jpg
    
    https://i.imgur.com/QaWV1Oe.jpg
    
windows
  • 2 2 个回答
  • 58 Views

2 个回答

  • Voted
  1. Best Answer
    GeeMack
    2023-12-12T08:44:28+08:002023-12-12T08:44:28+08:00

    使用 Windows 11 上的 ImageMagick v7,我使用此命令从几乎任何输入图像制作图标......

    magick image.jpg -gravity center -extent 1:1# ^
       -define icon:auto-resize="256,128,64,48,32,24,16" result.ico
    

    它以“-extent 1:1#”开头,将输入图像的画布扩展到 1:1 的比例。“#”标志告诉它根据需要添加画布以实现 1:1 的比例。

    该命令继续处理该方形图像,并使用 IM 的图标大小定义,它将输出一个包含指定大小的图标。

    • 2
  2. ElektroStudios
    2023-12-12T08:21:26+08:002023-12-12T08:21:26+08:00

    我能想到的解决这个问题的唯一解决方案是一个脚本化解决方案来获取和评估输入图像的宽度和高度,然后决定是否在magick.exe<参数中使用“ ”或“ ”标志。>

    因此,这是一个PowerShell脚本,它将递归搜索 bmp、jpeg/jpg、png 和 webp 文件,并将它们转换为 ico。它似乎按预期工作,将图像居中并缩小或放大以适应最近的画布边缘,同时保持纵横比。

    $imageMagickFullPath = "C:\Program Files\ImageMagick-7.1.1-Q8\magick.exe"
    
    $exts = @('.bmp', '.jpeg', '.jpg', '.png', '.webp')
    $files = Get-ChildItem -LiteralPath (Get-Location) -Filter "*.*" -Recurse | Where-Object { $exts -contains $_.Extension.ToLower() }
    $tempDir = [System.IO.Path]::GetTempPath()
    
    Add-Type -AssemblyName System.Drawing
    
    foreach ($file in $files) {
        Write-Host "Converting to icon: $($file.FullName)"
    
        $fileName = [System.IO.Path]::GetFileNameWithoutExtension($file.Name)
        $outIconFilePath = $file.Directory.FullName + "\" + $fileName + ".ico"
        $layerFilePaths = @()
    
        $image  = [System.Drawing.Image]::FromFile($file.FullName)
        $width  = $image.Width
        $height = $image.Height
        $image.Dispose()
    
        # Create icon layers.
        $sizes = @(256, 128, 96, 64, 32, 24, 16)
        foreach ($size in $sizes) {
            $layerFilePath = Join-Path -Path $tempDir -ChildPath "icon_layer-$sizex$size.png"
            $layerFilePaths += $layerFilePath
    
            if ($width -gt $size) {
                $args = "convert `"$($file.FullName)`" -resize $size>x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
            } elseif ($width -le $size) {
                if ($height -lt $size) {
                    $args = "convert `"$($file.FullName)`" -resize $size<x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
                } elseif ($height -gt $size) {
                    $args = "convert `"$($file.FullName)`" -resize $size>x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
                } else { # ($height -eq $size)
                    $args = "convert `"$($file.FullName)`" -resize       x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
                }
            }
    
            $procStartInfo = New-Object System.Diagnostics.ProcessStartInfo
            $procStartInfo.FileName = $imageMagickFullPath
            $procStartInfo.Arguments = $args
            $procStartInfo.UseShellExecute = $false
            $process = New-Object System.Diagnostics.Process
            $process.StartInfo = $procStartInfo
            $process.Start() | Out-Null
            $process.WaitForExit()
        }
    
        # Combine layers to create the icon file.
        $procStartInfo = New-Object System.Diagnostics.ProcessStartInfo
        $procStartInfo.FileName = $imageMagickFullPath
        $procStartInfo.Arguments = (($layerFilePaths | ForEach-Object { "`"$_`"" }) -join ' ') + " " + "`"$outIconFilePath`""
        $procStartInfo.UseShellExecute = $false
        $process = New-Object System.Diagnostics.Process
        $process.StartInfo = $procStartInfo
        $process.Start() | Out-Null
        $process.WaitForExit()
    }
    
    Write-Host "operation Completed."
    Write-Host ""
    Write-Host "Press any key to exit..."
    [System.Console]::ReadKey($true)
    Exit(0)
    

    上面代码中最重要且相关的部分是这个条件块:

    if ($width -gt $size) {
        $args = "convert `"$($file.FullName)`" -resize $size>x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
    } elseif ($width -le $size) {
        if ($height -lt $size) {
            $args = "convert `"$($file.FullName)`" -resize $size<x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
        } elseif ($height -gt $size) {
            $args = "convert `"$($file.FullName)`" -resize $size>x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
        } else { # ($height -eq $size)
            $args = "convert `"$($file.FullName)`" -resize       x$size -background transparent -gravity center -extent $size^x$size^ -quality 100 `"$layerFilePath`""
        }
    }
    

    更新:

    @GeeMack使用 PowerShell 的解决方案:

    $magickFilePath = "C:\Program Files\ImageMagick-7.1.1-Q8\magick.exe"
    
    $magickArgs = @('-define icon:auto-resize="256,128,96,64,48,32,24,16"',
                    '-background transparent',
                    '-gravity center',
                    '-extent 1:1#', 
                    '-quality 100'
                   )
    
    $exts = @('.bmp', '.jpeg', '.jpg', '.png', '.webp')
    $files = Get-ChildItem -LiteralPath (Get-Location) -Filter "*.*" -Recurse | Where-Object { $exts -contains $_.Extension.ToLower() }
    
    foreach ($file in $files) {
        Write-Host "Converting to icon: $($file.FullName)"
    
        $fileName = [System.IO.Path]::GetFileNameWithoutExtension($file.Name)
        $outIconFilePath = $file.Directory.FullName + "\" + $fileName + ".ico"
    
        $procStartInfo = New-Object System.Diagnostics.ProcessStartInfo
        $procStartInfo.FileName = $magickFilePath
        $procStartInfo.Arguments = "`"$($file.FullName)`" $($magickArgs -join ' ') `"$outIconFilePath`""
        $procStartInfo.UseShellExecute = $false
        $process = New-Object System.Diagnostics.Process
        $process.StartInfo = $procStartInfo
        $process.Start() | Out-Null
        $process.WaitForExit()
    }
    
    Write-Host "operation Completed."
    Write-Host ""
    Write-Host "Press any key to exit..."
    [System.Console]::ReadKey($true)
    Exit(0)
    
    • 0

相关问题

  • C++ 完全读取文件,其中大小>2GB (Win64)

  • Windows Palo Alto Cortex XDR BSOD,带错误检查 0x139

  • 我无法在我的 go 项目中导入本地包

  • KERNEL32.DLL 总是加载到 Windows 进程中的第三个模块吗?

  • 这个不安全的 Rust 代码有什么问题,所以它可以在 Windows 上运行,但不能在 Ubuntu 上运行?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve