[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7911":3},{"id":4,"name":5,"fullName":6,"owner":5,"repo":5,"description":7,"homepage":8,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":17,"rankGlobal":9,"rankLanguage":9,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":15,"starSnapshotCount":15,"syncStatus":25,"lastSyncTime":26,"discoverSource":27},7911,"minimagick","minimagick\u002Fminimagick","mini replacement for RMagick","https:\u002F\u002Frubydoc.info\u002Fgems\u002Fmini_magick",null,"Ruby",2863,348,43,5,0,12,29.63,"MIT License",false,"master",[],"2026-06-12 02:01:46","# MiniMagick\n[![Gem Version](https:\u002F\u002Fimg.shields.io\u002Fgem\u002Fv\u002Fmini_magick.svg)](http:\u002F\u002Frubygems.org\u002Fgems\u002Fmini_magick)\n[![Gem Downloads](https:\u002F\u002Fimg.shields.io\u002Fgem\u002Fdt\u002Fmini_magick.svg)](http:\u002F\u002Frubygems.org\u002Fgems\u002Fmini_magick)\n[![CI](https:\u002F\u002Fgithub.com\u002Fminimagick\u002Fminimagick\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fminimagick\u002Fminimagick\u002Factions\u002Fworkflows\u002Fci.yml)\n[![Code Climate](https:\u002F\u002Fcodeclimate.com\u002Fgithub\u002Fminimagick\u002Fminimagick\u002Fbadges\u002Fgpa.svg)](https:\u002F\u002Fcodeclimate.com\u002Fgithub\u002Fminimagick\u002Fminimagick)\n\nA ruby wrapper for [ImageMagick](http:\u002F\u002Fimagemagick.org\u002F) command line.\n\n## Why?\n\nI was using [RMagick](https:\u002F\u002Fgithub.com\u002Frmagick\u002Frmagick) and loving it, but it\nwas eating up huge amounts of memory. Even a simple script would use over 100MB\nof RAM. On my local machine this wasn't a problem, but on my hosting server the\nruby apps would crash because of their 100MB memory limit.\n\n## Solution!\n\nUsing MiniMagick the ruby processes memory remains small (it spawns\nImageMagick's command line program mogrify which takes up some memory as well,\nbut is much smaller compared to RMagick). See [Thinking of switching from\nRMagick?](#thinking-of-switching-from-rmagick) below.\n\nMiniMagick gives you access to all the command line options ImageMagick has\n(found [here](http:\u002F\u002Fwww.imagemagick.org\u002Fscript\u002Fcommand-line-options.php)).\n\n## Requirements\n\nImageMagick command-line tool has to be installed. You can check if you have it\ninstalled by running\n\n```sh\n$ magick -version\nVersion: ImageMagick 7.1.1-33 Q16-HDRI aarch64 22263 https:\u002F\u002Fimagemagick.org\nCopyright: (C) 1999 ImageMagick Studio LLC\nLicense: https:\u002F\u002Fimagemagick.org\u002Fscript\u002Flicense.php\nFeatures: Cipher DPC HDRI Modules OpenMP(5.0)\nDelegates (built-in): bzlib fontconfig freetype gslib heic jng jp2 jpeg jxl lcms lqr ltdl lzma openexr png ps raw tiff webp xml zlib zstd\nCompiler: gcc (4.2)\n```\n\n## Installation\n\nAdd the gem to your Gemfile:\n\n```sh\n$ bundle add mini_magick\n```\n\n## Information\n\n* [API documentation](https:\u002F\u002Frubydoc.info\u002Fgems\u002Fmini_magick)\n\n## Usage\n\nLet's first see a basic example of resizing an image.\n\n```rb\nrequire \"mini_magick\"\n\nimage = MiniMagick::Image.open(\"input.jpg\")\nimage.path #=> \"\u002Fvar\u002Ffolders\u002Fk7\u002F6zx6dx6x7ys3rv3srh0nyfj00000gn\u002FT\u002Fmagick20140921-75881-1yho3zc.jpg\"\nimage.resize \"100x100\"\nimage.format \"png\"\nimage.write \"output.png\"\n```\n\n`MiniMagick::Image.open` makes a copy of the image, and further methods modify\nthat copy (the original stays untouched). We then\n[resize](http:\u002F\u002Fwww.imagemagick.org\u002Fscript\u002Fcommand-line-options.php#resize)\nthe image, and write it to a file. The writing part is necessary because\nthe copy is just temporary, it gets garbage collected when we lose reference\nto the image.\n\n`MiniMagick::Image.open` also accepts URLs, and options passed in will be\nforwarded to [open-uri](https:\u002F\u002Fgithub.com\u002Fruby\u002Fopen-uri).\n\n```rb\nimage = MiniMagick::Image.open(\"http:\u002F\u002Fexample.com\u002Fimage.jpg\")\nimage.contrast\nimage.write(\"from_internets.jpg\")\n```\n\nOn the other hand, if we want the original image to actually *get* modified,\nwe can use `MiniMagick::Image.new`.\n\n```rb\nimage = MiniMagick::Image.new(\"input.jpg\")\nimage.path #=> \"input.jpg\"\nimage.resize \"100x100\"\n# Not calling #write, because it's not a copy\n```\n\n### Combine options\n\nWhile using methods like `#resize` directly is convenient, if we use more\nmethods in this way, it quickly becomes inefficient, because it calls the\ncommand on each methods call. `MiniMagick::Image#combine_options` takes\nmultiple options and from them builds one single command.\n\n```rb\nimage.combine_options do |b|\n  b.resize \"250x200>\"\n  b.rotate \"-90\"\n  b.flip\nend # the command gets executed\n```\n\nAs a handy shortcut, `MiniMagick::Image.new` also accepts an optional block\nwhich is used to `combine_options`.\n\n```rb\nimage = MiniMagick::Image.new(\"input.jpg\") do |b|\n  b.resize \"250x200>\"\n  b.rotate \"-90\"\n  b.flip\nend # the command gets executed\n```\n\nThe yielded builder is an instance of `MiniMagick::Tool`. To learn more\nabout its interface, see [Tools](#tools) below.\n\n### Attributes\n\nA `MiniMagick::Image` has various handy attributes.\n\n```rb\nimage.type        #=> \"JPEG\"\nimage.width       #=> 250\nimage.height      #=> 300\nimage.dimensions  #=> [250, 300]\nimage.size        #=> 3451 (in bytes)\nimage.colorspace  #=> \"DirectClass sRGB\"\nimage.exif        #=> {\"DateTimeOriginal\" => \"2013:09:04 08:03:39\", ...}\nimage.resolution  #=> [75, 75]\nimage.signature   #=> \"60a7848c4ca6e36b8e2c5dea632ecdc29e9637791d2c59ebf7a54c0c6a74ef7e\"\n```\n\nIf you need more control, you can also access [raw image\nattributes](http:\u002F\u002Fwww.imagemagick.org\u002Fscript\u002Fescape.php):\n\n```rb\nimage[\"%[gamma]\"] # \"0.9\"\n```\n\nTo get the all information about the image, MiniMagick gives you a handy method\nwhich returns the output from `magick input.jpg json:`:\n\n```rb\nimage.data #=>\n# {\n#   \"format\": \"JPEG\",\n#   \"mimeType\": \"image\u002Fjpeg\",\n#   \"class\": \"DirectClass\",\n#   \"geometry\": {\n#     \"width\": 200,\n#     \"height\": 276,\n#     \"x\": 0,\n#     \"y\": 0\n#   },\n#   \"resolution\": {\n#     \"x\": \"300\",\n#     \"y\": \"300\"\n#   },\n#   \"colorspace\": \"sRGB\",\n#   \"channelDepth\": {\n#     \"red\": 8,\n#     \"green\": 8,\n#     \"blue\": 8\n#   },\n#   \"quality\": 92,\n#   \"properties\": {\n#     \"date:create\": \"2016-07-11T19:17:53+08:00\",\n#     \"date:modify\": \"2016-07-11T19:17:53+08:00\",\n#     \"exif:ColorSpace\": \"1\",\n#     \"exif:ExifImageLength\": \"276\",\n#     \"exif:ExifImageWidth\": \"200\",\n#     \"exif:ExifOffset\": \"90\",\n#     \"exif:Orientation\": \"1\",\n#     \"exif:ResolutionUnit\": \"2\",\n#     \"exif:XResolution\": \"300\u002F1\",\n#     \"exif:YResolution\": \"300\u002F1\",\n#     \"icc:copyright\": \"Copyright (c) 1998 Hewlett-Packard Company\",\n#     \"icc:description\": \"sRGB IEC61966-2.1\",\n#     \"icc:manufacturer\": \"IEC http:\u002F\u002Fwww.iec.ch\",\n#     \"icc:model\": \"IEC 61966-2.1 Default RGB colour space - sRGB\",\n#     \"jpeg:colorspace\": \"2\",\n#     \"jpeg:sampling-factor\": \"1x1,1x1,1x1\",\n#     \"signature\": \"1b2336f023e5be4a9f357848df9803527afacd4987ecc18c4295a272403e52c1\"\n#   },\n#   ...\n# }\n```\n\n### Pixels\n\nWith MiniMagick you can retrieve a matrix of image pixels, where each member of\nthe matrix is a 3-element array of numbers between 0-255, one for each range of\nthe RGB color channels.\n\n```rb\nimage = MiniMagick::Image.open(\"image.jpg\")\npixels = image.get_pixels\npixels[3][2][1] # the green channel value from the 4th-row, 3rd-column pixel\n```\n\nIt can also be called after applying transformations:\n\n```rb\nimage = MiniMagick::Image.open(\"image.jpg\")\nimage.crop \"20x30+10+5\"\nimage.colorspace \"Gray\"\npixels = image.get_pixels\n```\n\n### Pixels To Image\n\nSometimes when you have pixels and want to create image from pixels, you can do this to form an image:\n\n```rb\nimage = MiniMagick::Image.open('\u002FUsers\u002Frabin\u002Finput.jpg')\npixels = image.get_pixels\ndepth = 8\ndimension = [image.width, image.height]\nmap = 'rgb'\nimage = MiniMagick::Image.get_image_from_pixels(pixels, dimension, map, depth ,'jpg')\nimage.write('\u002FUsers\u002Frabin\u002Foutput.jpg')\n```\n\nIn this example, the returned pixels should now have equal R, G, and B values.\n\n### Configuration\n\nHere are the available configuration options with their default values:\n\n```rb\nMiniMagick.configure do |config|\n  config.timeout = nil # number of seconds IM commands may take\n  config.errors = true # raise errors non nonzero exit status\n  config.warnings = true # forward warnings to standard error\n  config.tmpdir = Dir.tmpdir # alternative directory for tempfiles\n  config.logger = Logger.new($stdout) # where to log IM commands\n  config.cli_prefix = nil # add prefix to all IM commands\n  config.cli_env = {} # environment variables to set for IM commands\n  config.restricted_env = false # when true, block IM commands from accessing system environment variables other than those in cli_env\nend\n```\n\nFor a more information, see\n[Configuration](https:\u002F\u002Frubydoc.info\u002Fgems\u002Fmini_magick\u002FMiniMagick\u002FConfiguration) API documentation.\n\n### Composite\n\nMiniMagick also allows you to\n[composite](http:\u002F\u002Fwww.imagemagick.org\u002Fscript\u002Fcomposite.php) images:\n\n```rb\nfirst_image  = MiniMagick::Image.new(\"first.jpg\")\nsecond_image = MiniMagick::Image.new(\"second.jpg\")\nresult = first_image.composite(second_image) do |c|\n  c.compose \"Over\"    # OverCompositeOp\n  c.geometry \"+20+20\" # copy second_image onto first_image from (20, 20)\nend\nresult.write \"output.jpg\"\n```\n\n### Layers\u002FFrames\u002FPages\n\nFor multilayered images you can access its layers.\n\n```rb\ngif.frames #=> [...]\npdf.pages  #=> [...]\npsd.layers #=> [...]\n\ngif.frames.each_with_index do |frame, idx|\n  frame.write(\"frame#{idx}.jpg\")\nend\n```\n\n### Image validation\n\nYou can test whether an image is valid by running it through `identify`:\n\n```rb\nimage.valid?\nimage.validate! # raises MiniMagick::Invalid if image is invalid\n```\n\n### Logging\n\nYou can choose to log MiniMagick commands and their execution times:\n\n```rb\nMiniMagick.logger.level = Logger::DEBUG\n```\n```\nD, [2016-03-19T07:31:36.755338 #87191] DEBUG -- : [0.01s] identify \u002Fvar\u002Ffolders\u002Fk7\u002F6zx6dx6x7ys3rv3srh0nyfj00000gn\u002FT\u002Fmini_magick20160319-87191-1ve31n1.jpg\n```\n\nIn Rails you'll probably want to set `MiniMagick.logger = Rails.logger`.\n\n## Tools\n\nIf you prefer not to use the `MiniMagick::Image` abstraction, you can use ImageMagick's command-line tools directly:\n\n```rb\nMiniMagick.convert do |convert|\n  convert \u003C\u003C \"input.jpg\"\n  convert.resize(\"100x100\")\n  convert.negate\n  convert \u003C\u003C \"output.jpg\"\nend #=> `magick input.jpg -resize 100x100 -negate output.jpg`\n\n# OR\n\nconvert = MiniMagick.convert\nconvert \u003C\u003C \"input.jpg\"\nconvert.resize(\"100x100\")\nconvert.negate\nconvert \u003C\u003C \"output.jpg\"\nconvert.call #=> `magick input.jpg -resize 100x100 -negate output.jpg`\n```\n\nThis way of using MiniMagick is highly recommended if you want to maximize performance of your image processing. There are class methods for each CLI tool: `animate`, `compare`, `composite`, `conjure`, `convert`, `display`, `identify`, `import`, `mogrify` and `stream`. The `MiniMagick.convert` method will use `magick` on ImageMagick 7 and `convert` on ImageMagick 6.\n\n### Appending\n\nThe most basic way of building a command is appending strings:\n\n```rb\nMiniMagick.convert do |convert|\n  convert \u003C\u003C \"input.jpg\"\n  convert.merge! [\"-resize\", \"500x500\", \"-negate\"]\n  convert \u003C\u003C \"output.jpg\"\nend\n```\n\nNote that it is important that every command you would pass to the command line\nhas to be separated with `\u003C\u003C`, e.g.:\n\n```rb\n# GOOD\nconvert \u003C\u003C \"-resize\" \u003C\u003C \"500x500\"\n\n# BAD\nconvert \u003C\u003C \"-resize 500x500\"\n```\n\nShell escaping is also handled for you. If an option has a value that has\nspaces inside it, just pass it as a regular string.\n\n```rb\nconvert \u003C\u003C \"-distort\"\nconvert \u003C\u003C \"Perspective\"\nconvert \u003C\u003C \"0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35\"\n```\n```\nmagick -distort Perspective '0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35'\n```\n\n### Methods\n\nInstead of passing in options directly, you can use Ruby methods:\n\n```rb\nconvert.resize(\"500x500\")\nconvert.rotate(90)\nconvert.distort(\"Perspective\", \"0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35\")\n```\n\n### Chaining\n\nEvery method call returns `self`, so you can chain them to create logical groups.\n\n```rb\nMiniMagick.convert do |convert|\n  convert \u003C\u003C \"input.jpg\"\n  convert.clone(0).background('gray').shadow('80x5+5+5')\n  convert.negate\n  convert \u003C\u003C \"output.jpg\"\nend\n```\n\n### \"Plus\" options\n\n```rb\nMiniMagick.convert do |convert|\n  convert \u003C\u003C \"input.jpg\"\n  convert.repage.+\n  convert.distort.+(\"Perspective\", \"more args\")\nend\n```\n```\nmagick input.jpg +repage +distort Perspective 'more args'\n```\n\n### Stacks\n\n```rb\nMiniMagick.convert do |convert|\n  convert \u003C\u003C \"wand.gif\"\n\n  convert.stack do |stack|\n    stack \u003C\u003C \"wand.gif\"\n    stack.rotate(30)\n    stack.foo(\"bar\", \"baz\")\n  end\n  # or\n  convert.stack(\"wand.gif\", { rotate: 30, foo: [\"bar\", \"baz\"] })\n\n  convert \u003C\u003C \"images.gif\"\nend\n```\n```\nmagick wand.gif \\( wand.gif -rotate 90 -foo bar baz \\) images.gif\n```\n\n### STDIN and STDOUT\n\nIf you want to pass something to standard input, you can pass the `:stdin`\noption to `#call`:\n\n```rb\nidentify = MiniMagick.identify\nidentify.stdin # alias for \"-\"\nidentify.call(stdin: image_content)\n```\n\nMiniMagick also has `#stdout` alias for \"-\" for outputting file contents to\nstandard output:\n\n```rb\ncontent = MiniMagick.convert do |convert|\n  convert \u003C\u003C \"input.jpg\"\n  convert.auto_orient\n  convert.stdout # alias for \"-\"\nend\n```\n\n### Capturing STDERR\n\nSome MiniMagick tools such as `compare` output the result of the command on\nstandard error, even if the command succeeded. The result of\n`MiniMagick::Tool#call` is always the standard output, but if you pass it a\nblock, it will yield the stdout, stderr and exit status of the command:\n\n```rb\ncompare = MiniMagick.compare\n# build the command\ncompare.call do |stdout, stderr, status|\n  # ...\nend\n```\n\n## Configuring\n\n### GraphicsMagick\n\nAs of MiniMagick 5+, [GraphicsMagick](http:\u002F\u002Fwww.graphicsmagick.org\u002F) isn't\nofficially supported. This means its installation won't be auto-detected, and no\nattempts will be made to handle differences in GraphicsMagick API or output.\n\nHowever, you can still configure MiniMagick to use it:\n\n```rb\nMiniMagick.configure do |config|\n  config.graphicsmagick = true\nend\n```\n\nSome MiniMagick features won't be supported, such as global timeout,\n`MiniMagick::Image#data` and `MiniMagick::Image#exif`.\n\n### Limiting resources\n\nImageMagick supports a number of [environment variables] for controlling its\nresource limits. For example, you can enforce memory or execution time limits by\nsetting the following:\n\n```rb\nMiniMagick.configure do |config|\n  config.cli_env = {\n    \"MAGICK_MEMORY_LIMIT\" => \"128MiB\",\n    \"MAGICK_MAP_LIMIT\" => \"64MiB\",\n    \"MAGICK_TIME_LIMIT\" => \"30\"\n  }\nend\n```\n\nFor time limit you can also use the `timeout` configuration:\n\n```rb\nMiniMagick.configure do |config|\n  config.timeout = 30 # 30 seconds\nend\n```\n\n### Changing temporary directory\n\nImageMagick allows you to change the temporary directory to process the image file:\n\n```rb\nMiniMagick.configure do |config|\n  config.tmpdir = File.join(Dir.tmpdir, \"\u002Fmy\u002Fnew\u002Ftmp_dir\")\nend\n```\n\nThe example directory `\u002Fmy\u002Fnew\u002Ftmp_dir` must exist and must be writable.\n\nIf not configured, it will default to `Dir.tmpdir`.\n\n### Ignoring STDERR\n\nIf you're receiving warnings from ImageMagick that you don't care about, you\ncan avoid them being forwarded to standard error:\n\n```rb\nMiniMagick.configure do |config|\n  config.warnings = false\nend\n```\n\n### Avoiding raising errors\n\nThis gem raises an error when ImageMagick returns a nonzero exit code.\nSometimes, however, ImageMagick returns nonzero exit codes when the command\nactually went ok. In these cases, to avoid raising errors, you can add the\nfollowing configuration:\n\n```rb\nMiniMagick.configure do |config|\n  config.errors = false\nend\n```\n\nYou can also pass `errors: false` to individual commands:\n\n```rb\nMiniMagick.identify(errors: false) do |b|\n  b.help\nend\n```\n\n## Thinking of switching from RMagick?\n\nUnlike RMagick, MiniMagick is a much thinner wrapper around ImageMagick.\n\n* To piece together MiniMagick commands refer to the [Mogrify\n  Documentation](https:\u002F\u002Fimagemagick.org\u002Fscript\u002Fmogrify.php). For instance\n  you can use the `-flop` option as `image.flop`.\n* Operations on a MiniMagick image tend to happen in-place as `image.trim`,\n  whereas RMagick has both copying and in-place methods like `image.trim` and\n  `image.trim!`.\n* To open files with MiniMagick you use `MiniMagick::Image.open` as you would\n  `Magick::Image.read`. To open a file and directly edit it, use\n  `MiniMagick::Image.new`.\n\n[environment variables]: https:\u002F\u002Fimagemagick.org\u002Fscript\u002Fresources.php#environment\n","MiniMagick 是一个轻量级的 Ruby 库，用于替代 RMagick 以处理图像。它通过调用 ImageMagick 的命令行工具来实现图像处理功能，从而显著减少了内存占用。核心功能包括图像的打开、调整大小、格式转换以及保存等操作，并且支持 ImageMagick 所有的命令行选项。由于其低内存消耗的特点，MiniMagick 特别适用于服务器端环境或对资源限制有严格要求的应用场景中，如云服务中的图片处理任务。",2,"2026-06-11 03:15:02","top_language"]