{"id":17656540,"url":"https://github.com/imdrasil/crymagick","last_synced_at":"2025-05-07T09:47:30.934Z","repository":{"id":47199044,"uuid":"109116908","full_name":"imdrasil/crymagick","owner":"imdrasil","description":"A crystal wrapper for ImageMagick command line.","archived":false,"fork":false,"pushed_at":"2021-09-08T20:37:08.000Z","size":1232,"stargazers_count":35,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-19T20:54:01.871Z","etag":null,"topics":["crystal","image-processing","imagemagick","imagemagick-wrapper"],"latest_commit_sha":null,"homepage":null,"language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/imdrasil.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-01T10:17:12.000Z","updated_at":"2024-03-09T22:11:11.000Z","dependencies_parsed_at":"2022-08-12T13:20:14.527Z","dependency_job_id":null,"html_url":"https://github.com/imdrasil/crymagick","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imdrasil%2Fcrymagick","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imdrasil%2Fcrymagick/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imdrasil%2Fcrymagick/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imdrasil%2Fcrymagick/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imdrasil","download_url":"https://codeload.github.com/imdrasil/crymagick/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252854465,"owners_count":21814690,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crystal","image-processing","imagemagick","imagemagick-wrapper"],"created_at":"2024-10-23T14:33:27.370Z","updated_at":"2025-05-07T09:47:30.918Z","avatar_url":"https://github.com/imdrasil.png","language":"Crystal","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CryMagick [![Build Status](https://travis-ci.org/imdrasil/crymagick.svg)](https://travis-ci.org/imdrasil/crymagick) [![Latest Release](https://img.shields.io/github/release/imdrasil/crymagick.svg)](https://github.com/imdrasil/crymagick/releases)\n\n**CryMagick** is a [ImageMagick](http://imagemagick.org/) command line interface for crystal. Inspired by [minimagick](https://github.com/minimagick/minimagick).\n\n## Installation\n\nAdd this to your application's `shard.yml`:\n\n```yaml\ndependencies:\n  crymagick:\n    github: imdrasil/crymagick\n    version: 0.2.3\n```\n\n## Requirements\n\nImageMagick command-line tool \u003e= 7.0.8  has to be installed. You can check if you have it installed by running\n\n```shell\n$ convert -version\nVersion: ImageMagick 7.0.8-6 Q16 x86_64 2018-07-10 https://www.imagemagick.org\n```\n\n## Usage\n\nLet's first see a basic example of resizing an image.\n\n```crystal\nimage = CryMagick::Image.open(\"input.jpg\")\nimage.path #=\u003e \"/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/magick20140921-75881-1yho3zc.jpg\"\nimage.resize \"100x100\"\nimage.format \"png\"\nimage.write \"output.png\"\n```\n\n`CryMagick::Image.open` makes a copy of the image, and further methods modify that copy (the original stays untouched). We then resize the image, and write it to a file. The writing part is necessary because the copy is just temporary, it gets garbage collected when we lose reference to the image.\n\nOn the other hand, if we want the original image to actually get modified, we can use `CryMagick::Image.new`.\n\n### Combine options\n\nWhile using methods like `#resize` directly is convenient, if we use more methods in this way, it quickly becomes inefficient, because it calls the command on each methods call. `CryMagick::Image#combine_options` takes multiple options and from them builds one single command.\n\n```crystal\nimage.combine_options do |b|\n  b.resize \"250x200\u003e\"\n  b.rotate \"-90\"\n  b.flip\nend # the command gets executed\n```\n\nAs a handy shortcut, `CryMagick::Image.build` accepts an optional block which is used to combine_options.\n\n```crystal\nimage = CryMagick::Image.build(\"input.jpg\") do |b|\n  b.resize \"250x200\u003e\"\n  b.rotate \"-90\"\n  b.flip\nend # the command gets executed\n```\n\nThe yielded builder is an instance of `CryMagick::Tool::Mogrify`.\n\n### Attributes\n\nA `CryMagick::Image` has various handy attributes.\n\n```crystal\nimage.type        #=\u003e \"JPEG\"\nimage.mime_type   #=\u003e \"image/jpeg\"\nimage.width       #=\u003e 250\nimage.height      #=\u003e 300\nimage.dimensions  #=\u003e [250, 300]\nimage.size        #=\u003e 3451 (in bytes)\nimage.colorspace  #=\u003e \"DirectClass sRGB\"\nimage.exif        #=\u003e {\"DateTimeOriginal\" =\u003e \"2013:09:04 08:03:39\", ...}\nimage.resolution  #=\u003e [75, 75]\nimage.signature   #=\u003e \"60a7848c4ca6e36b8e2c5dea632ecdc29e9637791d2c59ebf7a54c0c6a74ef7e\"\n```\n\nIf you need more control, you can also access raw image attributes:\n\n```crystal\nimage[\"%[gamma]\"] # \"0.9\"\n```\n\nTo get the all information about the image, CryMagick gives you a handy method which returns the output from `identify -verbose` in hash format:\n\n```crystal\nimage.data #=\u003e\n# {\n#   \"format\": \"JPEG\",\n#   \"mimeType\": \"image/jpeg\",\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/1\",\n#     \"exif:YResolution\": \"300/1\",\n#     \"icc:copyright\": \"Copyright (c) 1998 Hewlett-Packard Company\",\n#     \"icc:description\": \"sRGB IEC61966-2.1\",\n#     \"icc:manufacturer\": \"IEC http://www.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### Configuration\n\n```crystal\nCryMagick::Configuration.configure do |config|\n  config.cli_path = \"some/path\"\n  config.whiny = false\nend\n```\n\n### Composite\n\nCryMagick allows to composite images:\n\n```crystal\nfirst_image  = CryMagick::Image.new(\"first.jpg\")\nsecond_image = CryMagick::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### Metal\n\nIf you want to be close to the metal, you can use ImageMagick's command-line tools directly.\n\n```crystal\nCryMagick::Tool::Mogrify.build do |mogrify|\n  mogrify.resize(\"100x100\")\n  mogrify.negate\n  mogrify \u003c\u003c \"image.jpg\"\nend #=\u003e `mogrify -resize 100x100 -negate image.jpg`\n\n# OR\n\nmogrify = CryMagick::Tool::Mogrify.new\nmogrify.resize(\"100x100\")\nmogrify.negate\nmogrify \u003c\u003c \"image.jpg\"\nmogrify.call #=\u003e `mogrify -resize 100x100 -negate image.jpg`\n```\n\nThis way of using CryMagick is highly recommended if you want to maximize performance of your image processing. Here are some of the features.\n\n#### Appending\n\nThe most basic way of building a command is appending strings:\n\n```crystal\nCryMagick::Tool::Convert.build do |convert|\n  convert \u003c\u003c \"input.jpg\"\n  convert.merge! [\"-resize\", \"500x500\", \"-negate\"]\n  convert \u003c\u003c \"output.jpg\"\nend\n```\n\n#### Methods\n\nInstead of passing in options directly, you can use pure methods:\n\n```crystal\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\n```crystal\nCryMagick::Tool::Convert.build 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\"\n\n```crystal\nCryMagick::Tool::Convert.build do |convert|\n  convert \u003c\u003c \"input.jpg\"\n  convert.repage.+\n  convert.distort.+(\"Perspective\", \"more args\")\nend\n# convert input.jpg +repage +distort Perspective 'more args'\n```\n\n#### Stack\n\n```crystal\nCryMagick::Tool::Convert.build do |convert|\n  convert \u003c\u003c \"wand.gif\"\n  convert.stack do |stack|\n    stack \u003c\u003c \"wand.gif\"\n    stack.rotate(30)\n  end\n  convert \u003c\u003c \"images.gif\"\nend\n```\n\n## Troubleshooting\n\n`CryMagick::Tool` uses `method_missing` macro so any method invocation with the invalid arguments will create a new method. To get a list of generated methods add `crymagick_debug` flag:\n\n```shell\n$ crystal run ./src/target.cr -Dcrymagic_debug\nCryMagick::Tool::Mogrify#resize(_arg0) is generated\nCryMagick::Tool::Mogrify#colorspace(_arg0) is generated\nCryMagick::Tool::Mogrify#crop(_arg0) is generated\n```\n\n## Development\n\nTo run test suite\n\n```shell\n$ make test\n```\n\nNext feature:\n- [ ] add graphicsmagick\n- [ ] add different image converting tools support\n\n## Contributing\n\n1. Fork it ( https://github.com/imdrasil/crymagick/fork )\n2. Create your feature branch (git checkout -b my-new-feature)\n3. Commit your changes (git commit -am 'Add some feature')\n4. Push to the branch (git push origin my-new-feature)\n5. Create a new Pull Request\n\n## Contributors\n\n- [imdrasil](https://github.com/imdrasil) Roman Kalnytskyi - creator, maintainer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimdrasil%2Fcrymagick","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimdrasil%2Fcrymagick","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimdrasil%2Fcrymagick/lists"}