├── .clang-format ├── .gitignore ├── .travis.yml ├── .travis_build_config.rb ├── LICENSE ├── README.md ├── appveyor.yml ├── appveyor_config.rb ├── docker ├── Dockerfile └── build_config.rb ├── mrbgem.rake ├── mrblib └── mrb_mrmagick.rb ├── mruby-mrmagick.gem ├── src ├── dummy_exif.h ├── mrb_mrmagick.c ├── mrb_mrmagick.h └── util.cpp └── test ├── mrb_mrmagick.rb └── mruby_mrmagick_test.c /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlinesLeft: false 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: All 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: All 18 | AlwaysBreakAfterReturnType: All 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | BeforeCatch: false 33 | BeforeElse: false 34 | IndentBraces: false 35 | BreakBeforeBinaryOperators: None 36 | BreakBeforeBraces: Linux 37 | BreakBeforeTernaryOperators: true 38 | BreakConstructorInitializersBeforeComma: false 39 | BreakAfterJavaFieldAnnotations: false 40 | BreakStringLiterals: true 41 | ColumnLimit: 110 42 | CommentPragmas: '^ IWYU pragma:' 43 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 44 | ConstructorInitializerIndentWidth: 2 45 | ContinuationIndentWidth: 2 46 | Cpp11BracedListStyle: true 47 | DerivePointerAlignment: false 48 | DisableFormat: false 49 | ExperimentalAutoDetectBinPacking: false 50 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 51 | IncludeCategories: 52 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 53 | Priority: 2 54 | - Regex: '^(<|"(gtest|isl|json)/)' 55 | Priority: 3 56 | - Regex: '.*' 57 | Priority: 1 58 | IncludeIsMainRegex: '$' 59 | IndentCaseLabels: false 60 | IndentWidth: 2 61 | IndentWrappedFunctionNames: false 62 | JavaScriptQuotes: Leave 63 | JavaScriptWrapImports: true 64 | KeepEmptyLinesAtTheStartOfBlocks: true 65 | MacroBlockBegin: '' 66 | MacroBlockEnd: '' 67 | MaxEmptyLinesToKeep: 1 68 | NamespaceIndentation: None 69 | ObjCBlockIndentWidth: 2 70 | ObjCSpaceAfterProperty: false 71 | ObjCSpaceBeforeProtocolList: true 72 | PenaltyBreakBeforeFirstCallParameter: 19 73 | PenaltyBreakComment: 300 74 | PenaltyBreakFirstLessLess: 120 75 | PenaltyBreakString: 1000 76 | PenaltyExcessCharacter: 1000000 77 | PenaltyReturnTypeOnItsOwnLine: 80 78 | PointerAlignment: Right 79 | ReflowComments: true 80 | SortIncludes: false 81 | SpaceAfterCStyleCast: false 82 | SpaceBeforeAssignmentOperators: true 83 | SpaceBeforeParens: ControlStatements 84 | SpaceInEmptyParentheses: false 85 | SpacesBeforeTrailingComments: 1 86 | SpacesInAngles: false 87 | SpacesInContainerLiterals: true 88 | SpacesInCStyleCastParentheses: false 89 | SpacesInParentheses: false 90 | SpacesInSquareBrackets: false 91 | Standard: Cpp11 92 | TabWidth: 8 93 | UseTab: Never 94 | ... 95 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | \#*\# 3 | .\#* 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - gcc 4 | - clang 5 | env: 6 | - MRUBY_VERSION=1.2.0 7 | - MRUBY_VERSION=1.3.0 8 | - MRUBY_VERSION=1.4.0 9 | before_install: 10 | - sudo apt-get -qq update 11 | install: 12 | - sudo apt-get -qq install rake bison git gperf texinfo libtiff-dev help2man 13 | before_script: 14 | - cd .. 15 | - git clone http://git.sv.gnu.org/r/autoconf.git 16 | - cd autoconf 17 | - aclocal -I m4 18 | - automake -a 19 | - autoconf 20 | - ./configure --prefix=/usr 21 | - make 22 | - sudo make install 23 | - cd .. 24 | - git clone -b ImageMagick-6 --depth 1 https://github.com/ImageMagick/ImageMagick.git 25 | - cd ImageMagick 26 | - echo $CC 27 | - CC="gcc" ./configure --prefix=/usr/local --without-xml --without-perl --disable-docs 28 | - make -j -l 4 29 | - which clang 30 | - sudo PATH=/usr/local/clang-3.4/bin:$PATH make install 31 | - export PATH=/usr/local/bin:$PATH 32 | - export LD_LIBRARY_PATH=/usr/local/lib 33 | - cd .. 34 | - git clone --depth 1 -b $MRUBY_VERSION https://github.com/mruby/mruby.git 35 | - cd mruby 36 | - cp -fp ../mruby-mrmagick/.travis_build_config.rb build_config.rb 37 | script: 38 | - rake test 39 | -------------------------------------------------------------------------------- /.travis_build_config.rb: -------------------------------------------------------------------------------- 1 | MRuby::Build.new do |conf| 2 | toolchain :gcc 3 | conf.gembox 'full-core' 4 | 5 | conf.gem '../mruby-mrmagick' 6 | end 7 | 8 | MRuby::Build.new('test') do |conf| 9 | toolchain :gcc 10 | 11 | enable_debug 12 | conf.enable_bintest 13 | conf.enable_test 14 | 15 | conf.gembox 'full-core' 16 | 17 | #conf.gem :git => 'https://github.com/iij/mruby-io.git' 18 | conf.gem '../mruby-mrmagick' 19 | end 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | mruby-mrmagick 2 | 3 | Copyright (c) Junichi Kajiwara 2015-2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | [ MIT license: http://www.opensource.org/licenses/mit-license.php ] 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mruby-mrmagick [![Build Status](https://travis-ci.org/kjunichi/mruby-mrmagick.png?branch=master)](https://travis-ci.org/kjunichi/mruby-mrmagick) [![Build status](https://ci.appveyor.com/api/projects/status/8ay7ic4abok7bjg2/branch/master?svg=true)](https://ci.appveyor.com/project/kjunichi/mruby-mrmagick/branch/master) 2 | 3 | ImageMagick binding for mruby. 4 | 5 | I don't know or use the whole ImageMagick library. 6 | I have deliberately let some modules out of these bindings in order to focus on parts I understand and/or have a need for. 7 | 8 | ## install by mrbgems 9 | 10 | - add conf.gem line to `build_config.rb` 11 | 12 | ```ruby 13 | MRuby::Build.new do |conf| 14 | 15 | # ... (snip) ... 16 | 17 | conf.gem :mgem => 'mruby-mrmagick' 18 | end 19 | ``` 20 | 21 | ## example 22 | 23 | ```ruby 24 | img = Mrmagick::ImageList.new("sample.png") # read image file. 25 | new_img = img.blur_image(0.0, 8.0) # returns new image which bluerd. 26 | new_img.write("blur.jpg") 27 | ``` 28 | 29 | ```ruby 30 | img = Mrmagick::ImageList.new("sample.jpg") # read image file. 31 | new_img = img.scale(0.5) # returns new image which scaled. 32 | new_img.write("half.png") 33 | ``` 34 | 35 | ```ruby 36 | img = Mrmagick::ImageList.new("sample.png") # read image file. 37 | img2 = img.blur_image(0.0, 8.0) # returns new image which bluerd. 38 | img3 = img2.scale(4) # returns new image which scaled. 39 | img3.write("blur_x4.jpg") 40 | ``` 41 | 42 | ```ruby 43 | img = Mrmagick::ImageList.new("sample.jpg") # read image file. 44 | img.get_exif_by_entry('GPSLatitude') 45 | 46 | ``` 47 | 48 | ```ruby 49 | img = Mrmagick::ImageList.new("sample.jpg") # read image file. 50 | img2 = img.blur_image(0.0, 8.0) # returns new image which bluerd. 51 | File.open("blob.jpg", "wb") {|f| 52 | f.print img2.to_blob 53 | } 54 | ``` 55 | 56 | ```ruby 57 | img = Mrmagick::ImageList.new("sample_with_exif.jpg") 58 | img.orientation # => 2 59 | img = img.auto_orient 60 | img.write("sample_ao.jpg") 61 | img = Mrmagick::ImageList.new("sample_ao.jpg") 62 | img.orientation # => 1 63 | ``` 64 | 65 | ## See also 66 | - [How to build one binary using with mruby cli](https://github.com/kjunichi/mruby-mrmagick/wiki/How-to-build-one-binary-using-with-mruby-cli) 67 | - [How to build h2o with mruby-mrmagick](https://github.com/kjunichi/mruby-mrmagick/wiki/How-to-build-h2o-with-mruby-mrmagick) 68 | - [Rubyist Magazine - RedDotRubyConf 2015 レポート](http://magazine.rubyist.net/?0051-RedDotRubyConf2015#l7) 69 | - [ngx_mrubyを使った簡単な画像変換サーバを数分で実装してみた - 人間とウェブの未来](http://hb.matsumoto-r.jp/entry/2015/05/13/234326) 70 | 71 | ## License 72 | under the MIT License: 73 | - see LICENSE file 74 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | 3 | os: Visual Studio 2015 4 | 5 | clone_depth: 50 6 | 7 | environment: 8 | matrix: 9 | # Visual Studio 2015 64bit 10 | - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat 11 | machine: amd64 12 | install: 13 | #- choco upgrade chocolatey 14 | - choco install wget 15 | - wget https://kjunichi.github.io/vendor/win_flex_bison-2.4.12.zip 16 | - mkdir win_flex_bison 17 | - cd win_flex_bison 18 | - unzip ..\win_flex_bison-2.4.12.zip 19 | - cd .. 20 | - dir 21 | - cd 22 | - cinst imagemagick.app -PackageParameters "InstallDevelopmentHeaders=true LegacySupport=true" 23 | - refreshenv 24 | - dir "C:\Program Files\ImageMagick-7.0.7-Q16" 25 | - convert -size "640x480" -background "#C0C0C0" -fill "#FFFF00" caption:"ABC" output.png 26 | - convert -scale 50% output.png dest.png 27 | - call "%visualcpp%" %machine% 28 | - set YACC=win_bison 29 | - set PATH=C:\projects\mruby-mrmagick\win_flex_bison;%PATH%; 30 | - where win_bison 31 | init: 32 | - call "%visualcpp%" %machine% 33 | - set YACC=win_bison 34 | build_script: 35 | - cd .. 36 | - git clone https://github.com/mruby/mruby.git 37 | - cd mruby 38 | - set MRUBY_CONFIG=..\mruby-mrmagick\appveyor_config.rb 39 | - rake all 40 | 41 | -------------------------------------------------------------------------------- /appveyor_config.rb: -------------------------------------------------------------------------------- 1 | MRuby::Build.new do |conf| 2 | toolchain :visualcpp 3 | conf.gembox 'default' 4 | conf.gem '../mruby-mrmagick' 5 | conf.enable_test 6 | end 7 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hone/mruby-cli 2 | RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y --no-install-recommends \ 3 | wget 4 | 5 | RUN mkdir /root/src 6 | WORKDIR /root/src 7 | RUN wget http://www.ijg.org/files/jpegsrc.v9b.tar.gz 8 | 9 | RUN tar xvf jpegsrc.v9b.tar.gz 10 | RUN cd jpeg-9b && ./configure --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32 && \ 11 | make && make install 12 | 13 | 14 | RUN wget http://zlib.net/zlib-1.2.8.tar.xz && \ 15 | wget http://download.sourceforge.net/libpng/libpng-1.6.21.tar.xz 16 | 17 | RUN tar xvf zlib-1.2.8.tar.xz && tar xvf libpng-1.6.21.tar.xz 18 | 19 | RUN cd zlib-1.2.8 && AR=i686-w64-mingw32-ar RANLIB=i686-w64-mingw32-ranlib CC=i686-w64-mingw32-gcc ./configure --prefix=/usr/i686-w64-mingw32 --static && \ 20 | make libz.a && make install 21 | #RUN cd zlib-1.2.8 && CHOST=i686-w64-mingw32 make -f win32/Makefile.gcc libz.a && make install 22 | 23 | RUN cd libpng-1.6.21 && ./configure --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32 && \ 24 | make && make install 25 | 26 | RUN git clone -b ImageMagick-6 --depth 1 https://github.com/ImageMagick/ImageMagick.git 27 | RUN wget https://raw.githubusercontent.com/Alexpux/MINGW-packages/master/mingw-w64-imagemagick/001-relocate.patch && \ 28 | wget https://raw.githubusercontent.com/Alexpux/MINGW-packages/master/mingw-w64-imagemagick/002-build-fixes.patch && \ 29 | wget https://raw.githubusercontent.com/Alexpux/MINGW-packages/master/mingw-w64-imagemagick/ImageMagick-6.8.8.1-mingw.patch 30 | RUN cp -r ImageMagick ImageMagick_mingw32 31 | RUN apt-get install -y --no-install-recommends mingw-w64-tools 32 | RUN rm /usr/i686-w64-mingw32/lib/lib*.dll.a /usr/i686-w64-mingw32/lib/lib*.la 33 | RUN cd ImageMagick_mingw32 && patch -p1 -i ../ImageMagick-6.8.8.1-mingw.patch && \ 34 | patch -p1 -i ../001-relocate.patch && \ 35 | patch -p1 -i ../002-build-fixes.patch && \ 36 | wget -O Makefile.in https://gist.githubusercontent.com/kjunichi/9ed9b4154bf84cf3d47f/raw/51ebfa4b7a7d4d5ece2063aab58d2ffcc0329ee0/Mingw_Makefile.in && \ 37 | ./configure --enable-static=yes --enable-shared=no --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32 --without-perl --disable-docs --without-xml && \ 38 | touch /usr/i686-w64-mingw32/include/intsafe.h && \ 39 | make -j -l 3 && make install 40 | #echo "" 41 | RUN cd jpeg-9b && make distclean && ./configure --host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32 && \ 42 | make && make install 43 | 44 | RUN cd zlib-1.2.8 &&make distclean && \ 45 | AR=x86_64-w64-mingw32-ar RANLIB=x86_64-w64-mingw32-ranlib CC=x86_64-w64-mingw32-gcc \ 46 | ./configure --prefix=/usr/x86_64-w64-mingw32 --static && \ 47 | make libz.a && make install 48 | 49 | RUN cd libpng-1.6.21 && make distclean && ./configure --host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32 && \ 50 | make && make install 51 | 52 | RUN rm /usr/x86_64-w64-mingw32/lib/lib*.dll.a /usr/x86_64-w64-mingw32/lib/lib*.la 53 | RUN cd ImageMagick_mingw32 && make distclean && \ 54 | ./configure --enable-static=yes --enable-shared=no --host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32 \ 55 | --without-perl --disable-docs --without-xml && \ 56 | touch /usr/x86_64-w64-mingw32/include/intsafe.h && \ 57 | make -j -l 2 && make install 58 | 59 | # Darwin 60 | 61 | RUN cd jpeg-9b && make distclean && CC=x86_64-apple-darwin14-clang LD=x86_64-apple-darwin14-ld ./configure --host=x86_64-apple-darwin14 --prefix=/usr/x86_64-apple-darwin14 && \ 62 | CFLAGS="-fPIC" make && make install 63 | 64 | RUN cd zlib-1.2.8 &&make distclean && \ 65 | AR=x86_64-apple-darwin14-ar RANLIB=x86_64-apple-darwin14-ranlib CC=x86_64-apple-darwin14-clang \ 66 | ./configure --prefix=/usr/x86_64-apple-darwin14 --static && \ 67 | make libz.a && make install 68 | 69 | RUN cd libpng-1.6.21 && make distclean && \ 70 | CC=x86_64-apple-darwin14-clang ./configure --host=x86_64-apple-darwin14 --prefix=/usr/x86_64-apple-darwin14 && \ 71 | make && make install 72 | 73 | RUN rm /usr/x86_64-apple-darwin14/lib/lib*.dylib /usr/x86_64-apple-darwin14/lib/lib*.la 74 | RUN cd ImageMagick && \ 75 | OSXCROSS_PKG_CONFIG_PATH=/usr/x86_64-apple-darwin14/lib/pkgconfig \ 76 | LDFLAGS=-L/usr/x86_64-apple-darwin14/lib CFLAGS=-I/usr/x86_64-apple-darwin14/include \ 77 | CC=x86_64-apple-darwin14-clang CXX=x86_64-apple-darwin14-clang++ \ 78 | ./configure --host=x86_64-apple-darwin14 --prefix=/usr/x86_64-apple-darwin14 \ 79 | --enable-static=yes --enable-shared=no --without-perl --disable-docs --without-xml &&\ 80 | make -j -l 2 && make install 81 | 82 | RUN cd jpeg-9b && make distclean && CC=i386-apple-darwin14-clang LD=i386-apple-darwin14-ld ./configure --host=i386-apple-darwin14 --prefix=/usr/i386-apple-darwin14 && \ 83 | CFLAGS="-fPIC" make && make install 84 | 85 | RUN cd zlib-1.2.8 &&make distclean && \ 86 | AR=i386-apple-darwin14-ar RANLIB=i386-apple-darwin14-ranlib CC=i386-apple-darwin14-clang \ 87 | ./configure --prefix=/usr/i386-apple-darwin14 --static && \ 88 | make libz.a && make install 89 | 90 | RUN cd libpng-1.6.21 && make distclean && \ 91 | CC=i386-apple-darwin14-clang ./configure --host=i386-apple-darwin14 --prefix=/usr/i386-apple-darwin14 && \ 92 | make && make install 93 | 94 | RUN rm /usr/i386-apple-darwin14/lib/lib*.dylib /usr/i386-apple-darwin14/lib/lib*.la 95 | RUN cd ImageMagick && \ 96 | make distclean && \ 97 | OSXCROSS_PKG_CONFIG_PATH=/usr/i386-apple-darwin14/lib/pkgconfig \ 98 | LDFLAGS=-L/usr/i386-apple-darwin14/lib CFLAGS=-I/usr/i386-apple-darwin14/include \ 99 | CC=i386-apple-darwin14-clang CXX=i386-apple-darwin14-clang++ \ 100 | ./configure --host=i386-apple-darwin14 --prefix=/usr/i386-apple-darwin14 \ 101 | --enable-static=yes --enable-shared=no --without-perl --disable-docs --without-xml &&\ 102 | make -j -l 2 && make install 103 | 104 | # Linux 105 | 106 | RUN cd jpeg-9b && make distclean && CFLAGS="-m32" ./configure --prefix=/usr/i686-pc-linux-gnu && \ 107 | make && make install 108 | 109 | RUN cd zlib-1.2.8 && make distclean && \ 110 | CFLAGS="-m32" ./configure --prefix=/usr/i686-pc-linux-gnu --static && \ 111 | make libz.a && make install 112 | 113 | RUN cd libpng-1.6.21 && make distclean && \ 114 | CFLAGS="-m32 -I/usr/i686-pc-linux-gnu/include" LDFLAGS="-L/usr/i686-pc-linux-gnu/lib" ./configure --prefix=/usr/i686-pc-linux-gnu && \ 115 | make && make install 116 | 117 | RUN rm /usr/i686-pc-linux-gnu/lib/lib*.so* /usr/i686-pc-linux-gnu/lib/lib*.la 118 | RUN cd ImageMagick && \ 119 | PKG_CONFIG_PATH=/usr/i686-pc-linux-gnu/lib/pkgconfig \ 120 | CXXFLAGS="-m32 -I/usr/i686-pc-linux-gnu/include" CFLAGS="-m32 -I/usr/i686-pc-linux-gnu/include" LDFLAGS="-L/usr/i686-pc-linux-gnu/lib" \ 121 | ./configure --prefix=/usr/i686-pc-linux-gnu \ 122 | --enable-static=yes --enable-shared=no --without-perl --disable-docs --without-xml &&\ 123 | make -j -l 2 && make install 124 | 125 | RUN cd jpeg-9b && make distclean && ./configure --prefix=/usr/x86_64-pc-linux-gnu && \ 126 | make && make install 127 | 128 | RUN cd zlib-1.2.8 && make distclean && \ 129 | ./configure --prefix=/usr/x86_64-pc-linux-gnu --static && \ 130 | make libz.a && make install 131 | 132 | RUN cd libpng-1.6.21 && make distclean && \ 133 | CFLAGS="-I/usr/x86_64-pc-linux-gnu/include" LDFLAGS="-L/usr/x86_64-pc-linux-gnu/lib" ./configure --prefix=/usr/x86_64-pc-linux-gnu --disable-shared --enable-static && \ 134 | make && make install 135 | 136 | RUN rm /usr/x86_64-pc-linux-gnu/lib/lib*.so* /usr/x86_64-pc-linux-gnu/lib/lib*.la 137 | RUN cd ImageMagick && \ 138 | PKG_CONFIG_PATH=/usr/x86_64-pc-linux-gnu/lib/pkgconfig \ 139 | CFLAGS="-I/usr/x86_64-pc-linux-gnu/include" LDFLAGS="-L/usr/x86_64-pc-linux-gnu/lib" \ 140 | ./configure --prefix=/usr/x86_64-pc-linux-gnu \ 141 | --enable-static=yes --enable-shared=no --without-perl --disable-docs --without-xml &&\ 142 | make -j -l 2 && make install 143 | -------------------------------------------------------------------------------- /docker/build_config.rb: -------------------------------------------------------------------------------- 1 | def gem_config(conf) 2 | #conf.gembox 'default' 3 | 4 | # be sure to include this gem (the cli app) 5 | conf.gem File.expand_path(File.dirname(__FILE__)) 6 | end 7 | 8 | def gem_config_cross(conf) 9 | conf.gem :github => 'kjunichi/mruby-mrmagick' 10 | gem_config(conf) 11 | end 12 | 13 | MRuby::Build.new do |conf| 14 | toolchain :clang 15 | 16 | conf.enable_bintest 17 | conf.enable_debug 18 | conf.enable_test 19 | 20 | gem_config(conf) 21 | end 22 | 23 | MRuby::CrossBuild.new('x86_64-pc-linux-gnu') do |conf| 24 | toolchain :gcc 25 | conf.host_target = 'x86_64-pc-linux-gnu' 26 | gem_config_cross(conf) 27 | end 28 | 29 | MRuby::CrossBuild.new('i686-pc-linux-gnu') do |conf| 30 | toolchain :gcc 31 | conf.host_target = 'i686-pc-linux-gnu' 32 | [conf.cc, conf.cxx, conf.linker].each do |cc| 33 | cc.flags << "-m32" 34 | end 35 | 36 | gem_config_cross(conf) 37 | end 38 | 39 | MRuby::CrossBuild.new('x86_64-apple-darwin14') do |conf| 40 | toolchain :clang 41 | 42 | [conf.cc, conf.linker].each do |cc| 43 | cc.command = 'x86_64-apple-darwin14-clang' 44 | end 45 | conf.cxx.command = 'x86_64-apple-darwin14-clang++' 46 | conf.archiver.command = 'x86_64-apple-darwin14-ar' 47 | 48 | conf.build_target = 'x86_64-pc-linux-gnu' 49 | conf.host_target = 'x86_64-apple-darwin14' 50 | 51 | gem_config_cross(conf) 52 | end 53 | 54 | MRuby::CrossBuild.new('i386-apple-darwin14') do |conf| 55 | toolchain :clang 56 | 57 | [conf.cc, conf.linker].each do |cc| 58 | cc.command = 'i386-apple-darwin14-clang' 59 | end 60 | conf.cxx.command = 'i386-apple-darwin14-clang++' 61 | conf.archiver.command = 'i386-apple-darwin14-ar' 62 | 63 | conf.build_target = 'i386-pc-linux-gnu' 64 | conf.host_target = 'i386-apple-darwin14' 65 | 66 | gem_config_cross(conf) 67 | end 68 | 69 | MRuby::CrossBuild.new('x86_64-w64-mingw32') do |conf| 70 | toolchain :gcc 71 | 72 | [conf.cc, conf.linker].each do |cc| 73 | cc.command = 'x86_64-w64-mingw32-gcc' 74 | end 75 | conf.cxx.command = 'x86_64-w64-mingw32-g++' 76 | conf.archiver.command = 'x86_64-w64-mingw32-gcc-ar' 77 | conf.exts.executable = ".exe" 78 | 79 | conf.build_target = 'x86_64-pc-linux-gnu' 80 | conf.host_target = 'x86_64-w64-mingw32' 81 | 82 | gem_config_cross(conf) 83 | end 84 | 85 | MRuby::CrossBuild.new('i686-w64-mingw32') do |conf| 86 | toolchain :gcc 87 | 88 | [conf.cc, conf.linker].each do |cc| 89 | cc.command = 'i686-w64-mingw32-gcc' 90 | end 91 | conf.cxx.command = 'i686-w64-mingw32-g++' 92 | conf.archiver.command = 'i686-w64-mingw32-gcc-ar' 93 | conf.exts.executable = ".exe" 94 | 95 | conf.build_target = 'i686-pc-linux-gnu' 96 | conf.host_target = 'i686-w64-mingw32' 97 | 98 | gem_config_cross(conf) 99 | end 100 | -------------------------------------------------------------------------------- /mrbgem.rake: -------------------------------------------------------------------------------- 1 | MRuby::Gem::Specification.new('mruby-mrmagick') do |spec| 2 | spec.license = 'MIT' 3 | spec.authors = 'Junichi Kajiwara' 4 | 5 | if build.kind_of?(MRuby::CrossBuild) 6 | ENV['PKG_CONFIG_PATH'] = "/usr/#{build.host_target}/lib/pkgconfig" 7 | spec.cxx.flags << "-I/usr/#{build.host_target}/include" 8 | magick_cflg = `/usr/#{build.host_target}/bin/Magick++-config --cxxflags --cppflags`.chomp! 9 | magick_libs = `/usr/#{build.host_target}/bin/Magick++-config --ldflags --libs`.chomp! 10 | else 11 | if ENV['OS'] == 'Windows_NT' 12 | imPaths = Dir.glob("c:/Program Files/ImageMagick-**").sort! 13 | 14 | imHomeD = imPaths[imPaths.size-1].gsub!('/','\\') 15 | imHome = imPaths[imPaths.size-1] 16 | spec.cc.flags << "/I \"#{imHomeD}\\include\"" 17 | spec.cxx.flags << "/I \"#{imHomeD}\\include\"" 18 | spec.linker.library_paths += ["#{imHome}/lib"] 19 | if imHome.include?("-6") then 20 | spec.linker.libraries += ['CORE_RL_magick_','CORE_RL_Magick++_','CORE_RL_wand_'] 21 | else 22 | spec.linker.libraries += ['CORE_RL_MagickCore_','CORE_RL_Magick++_','CORE_RL_MagickWand_'] 23 | end 24 | else 25 | magick_cflg = `Magick++-config --cxxflags --cppflags`.chomp! 26 | magick_libs = `Magick++-config --ldflags --libs`.chomp! 27 | 28 | magick_cflg.gsub!(/\n/," ") 29 | spec.cxx.flags << magick_cflg 30 | magick_libs.gsub!(/\n/," ") 31 | spec.linker.flags_before_libraries << magick_libs 32 | end 33 | end 34 | 35 | 36 | 37 | if build.kind_of?(MRuby::CrossBuild) 38 | spec.linker.flags_before_libraries << "-ljpeg -lpng -lz" 39 | if %w(i686-pc-linux-gnu x86_64-pc-linux-gnu).include?(build.host_target) 40 | spec.linker.flags_before_libraries << "-lgomp -lpthread" 41 | end 42 | if %w(i386-apple-darwin14 x86_64-apple-darwin14).include?(build.host_target) 43 | spec.linker.flags_before_libraries << "-lbz2" 44 | end 45 | if %w(i686-w64-mingw32 x86_64-w64-mingw32).include?(build.host_target) 46 | spec.linker.flags_before_libraries << "-Wl,-dn,-lgdi32 -Wl,-dn,-lgomp" 47 | end 48 | end 49 | 50 | spec.add_test_dependency 'mruby-io' 51 | spec.add_dependency 'mruby-array-ext' 52 | spec.add_dependency 'mruby-print' 53 | end 54 | 55 | MRuby.each_target do 56 | next if kind_of? MRuby::CrossBuild 57 | if ENV['OS'] == 'Windows_NT' 58 | require 'fileutils' 59 | imPaths = Dir.glob("c:/Program Files/ImageMagick-*.**").sort! 60 | imHome = imPaths[imPaths.size-1] 61 | FileUtils.mkdir_p("#{build_dir}/bin/") 62 | if imHome.include?("-6") then 63 | FileUtils.cp("#{imHome}/CORE_RL_magick_.dll", "#{build_dir}/bin/") 64 | FileUtils.cp("#{imHome}/CORE_RL_Magick++_.dll", "#{build_dir}/bin/") 65 | FileUtils.cp("#{imHome}/CORE_RL_wand_.dll", "#{build_dir}/bin/") 66 | else 67 | FileUtils.cp("#{imHome}/CORE_RL_MagickCore_.dll", "#{build_dir}/bin/") 68 | FileUtils.cp("#{imHome}/CORE_RL_Magick++_.dll", "#{build_dir}/bin/") 69 | FileUtils.cp("#{imHome}/CORE_RL_MagickWand_.dll", "#{build_dir}/bin/") 70 | end 71 | puts @name 72 | if @name == 'host' 73 | if imHome.include?("-6") then 74 | FileUtils.cp("#{imHome}/CORE_RL_magick_.dll", "#{MRUBY_ROOT}/bin/") 75 | FileUtils.cp("#{imHome}/CORE_RL_Magick++_.dll", "#{MRUBY_ROOT}/bin/") 76 | FileUtils.cp("#{imHome}/CORE_RL_wand_.dll", "#{MRUBY_ROOT}/bin/") 77 | else 78 | FileUtils.cp("#{imHome}/CORE_RL_MagickCore_.dll", "#{MRUBY_ROOT}/bin/") 79 | FileUtils.cp("#{imHome}/CORE_RL_Magick++_.dll", "#{MRUBY_ROOT}/bin/") 80 | FileUtils.cp("#{imHome}/CORE_RL_MagickWand_.dll", "#{MRUBY_ROOT}/bin/") 81 | end 82 | 83 | end 84 | end 85 | end -------------------------------------------------------------------------------- /mrblib/mrb_mrmagick.rb: -------------------------------------------------------------------------------- 1 | module Mrmagick 2 | class Magickcmd 3 | def initialize(_cmd) 4 | end 5 | end 6 | class Image 7 | def initialize(path) 8 | @origImagePath = path 9 | @exif = {} 10 | @isBlob = false 11 | # p @origImagePath 12 | # return self 13 | end 14 | 15 | def setParentPath(path) 16 | @parentPath = path 17 | end 18 | 19 | # Get width of the image. 20 | # 21 | # @return [Integer] width of the image. 22 | def columns 23 | Mrmagick::Capi.get_columns(self) 24 | end 25 | 26 | # Get height of the image. 27 | # 28 | # @return [Integer] height of the image. 29 | def rows 30 | Mrmagick::Capi.get_rows(self) 31 | end 32 | 33 | # Get format of the image. 34 | # 35 | # @return [String] format of the image. 36 | def format 37 | Mrmagick::Capi.get_format(self) 38 | end 39 | 40 | # Crop the image. 41 | # 42 | # @param [Integer] offset_x offset x. 43 | # @param [Integer] offset_y offset y. 44 | # @param [Integer] width width. 45 | # @param [Integer] height height. 46 | # @return [Image] cropped image. 47 | def crop(offset_x, offset_y, width, height) 48 | destImage = ImageList.createVirtualImageList 49 | srcImagePath = gen 50 | destImage.magickCommand("convert #{srcImagePath} -crop #{width}x#{height}+#{offset_x}+#{offset_y} #{destImage.getPath}") 51 | destImage 52 | end 53 | 54 | def get_exif_by_entry(key) 55 | @exifKey = key 56 | Mrmagick::Capi.get_exif_by_entry(self) 57 | end 58 | 59 | def set_exif_by_entry(key, value) 60 | @exif[key] = value 61 | end 62 | 63 | def setParentImage(images) 64 | @images.push(images) 65 | @images.flatten! 66 | end 67 | 68 | # Chcek cached Orientation 69 | # 70 | # @return [Boolean] has orientation. 71 | def hasCachedOrientation 72 | if @exif["Orientation"]==nil 73 | return false 74 | end 75 | return true 76 | end 77 | 78 | # Set parent orientation 79 | # 80 | # @param [Image] parent image. 81 | def setParentOrientation(img) 82 | if img.hasCachedOrientation 83 | @orientationv = img.orientation.to_i 84 | @exif["Orientation"]=img.orientation 85 | end 86 | end 87 | 88 | def magickCommand(cmd) 89 | if @cmd.nil? 90 | # 1番目のコマンドのソースパスを親のパス(実体のある画像ファイル)と仮定。 91 | params = cmd.split(' ') 92 | @parentPath = params[1] 93 | @cmd = [cmd] 94 | else 95 | @cmd.push(cmd) 96 | # p self 97 | end 98 | end 99 | 100 | def from_blob(blob) 101 | @isBlob = true 102 | @blob = blob 103 | #Mrmagick::Capi.from_blob(self, blob) 104 | end 105 | 106 | def to_blob 107 | Mrmagick::Capi.to_blob(self) 108 | end 109 | 110 | def write(path) 111 | @outpath = path 112 | Mrmagick::Capi.write(self) 113 | end 114 | 115 | def rotate(rot) 116 | destImage = ImageList.createVirtualImageList 117 | srcImagePath = gen 118 | # p srcImagePath 119 | destImage.magickCommand("convert #{srcImagePath} -rotate #{rot} #{destImage.getPath}") 120 | destImage 121 | end 122 | 123 | def flop 124 | destImage = ImageList.createVirtualImageList 125 | srcImagePath = gen 126 | destImage.magickCommand("convert #{srcImagePath} -flop #{destImage.getPath}") 127 | destImage 128 | end 129 | 130 | def flip 131 | # p "flip" 132 | destImage = ImageList.createVirtualImageList 133 | srcImagePath = gen 134 | destImage.magickCommand("convert #{srcImagePath} -flip #{destImage.getPath}") 135 | destImage 136 | end 137 | 138 | def transpose 139 | destImage = createVirtualImageList 140 | srcImagePath = gen 141 | destImage.magickCommand("convert #{srcImagePath} -rotate 90 #{destImage.getPath}") 142 | destImage.magickCommand("convert #{srcImagePath} -flop #{destImage.getPath}") 143 | destImage 144 | end 145 | 146 | def transverse 147 | destImage = createVirtualImageList 148 | srcImagePath = gen 149 | destImage.magickCommand("convert #{srcImagePath} -rotate 270 #{destImage.getPath}") 150 | destImage.magickCommand("convert #{srcImagePath} -flop #{destImage.getPath}") 151 | destImage 152 | end 153 | 154 | def orientation=(v) 155 | @exif["Orientation"] = v.to_s 156 | @orientationv = v 157 | end 158 | 159 | def orientation 160 | @exifKey = 'Orientation' 161 | if(@exif[@exifKey]!=nil && @exif[@exifKey]!="") 162 | return @exif[@exifKey] 163 | end 164 | #p "get real orientation!" 165 | orient = Mrmagick::Capi.get_exif_by_entry(self) 166 | @exif[@exifKey]=orient 167 | orient 168 | end 169 | 170 | def auto_orient 171 | orient = orientation 172 | case orient 173 | when '2' then 174 | destImage = flop 175 | when '3' then 176 | destImage = rotate(180) 177 | when '4' then 178 | destImage = flip 179 | when '5' then 180 | destImage = transpose 181 | when '6' then 182 | destImage = rotate(90) 183 | when '7' then 184 | destImage = transverse 185 | when '8' then 186 | destImage = roteate(270) 187 | else 188 | destImage = rotate(0) 189 | end 190 | destImage.orientation = 1 191 | destImage 192 | end 193 | 194 | def gen 195 | # 自分のファイルパスを出力する。 196 | return @origImagePath if @origImagePath.length > 0 197 | end 198 | 199 | def destroy! 200 | # 内部で隠し持ってた情報を全部ばれないように証拠隠滅する。 201 | end 202 | end 203 | class ImageList 204 | 205 | def initialize(*args) 206 | if(args.length==0) 207 | imagePath = "" 208 | else 209 | imagePath = args[0] 210 | end 211 | 212 | if imagePath.length == 0 213 | # 物理パスが指定されていない場合、仮想的にファイル名を生成し、保持する。 214 | # path = `uuidgen`.chomp! 215 | # path = Mrmagick::Capi.uuid() 216 | path = 'nofilepath' 217 | imagePath = path + '.png' 218 | @fRealFile = false 219 | else 220 | @fRealFile = true 221 | srcImagePath = imagePath 222 | end 223 | @images = [] 224 | 225 | @image = Mrmagick::Image.new(imagePath) 226 | @image.setParentPath(imagePath) 227 | @cmd = '' 228 | @frames = [] 229 | end 230 | 231 | def get_exif_by_entry(key) 232 | @image.get_exif_by_entry(key) 233 | end 234 | 235 | def set_exif_by_entry(key, value) 236 | @image.set_exif_by_entry(key, value) 237 | end 238 | 239 | def orientation=(v) 240 | @image.orientation = v 241 | end 242 | 243 | def orientation 244 | @image.orientation 245 | end 246 | 247 | def auto_orient 248 | orient = orientation 249 | case orient 250 | when '2' then 251 | destImage = flop 252 | when '3' then 253 | destImage = rotate(180) 254 | when '4' then 255 | destImage = flip 256 | when '5' then 257 | destImage = transpose 258 | when '6' then 259 | destImage = rotate(90) 260 | when '7' then 261 | destImage = transverse 262 | when '8' then 263 | destImage = rotate(270) 264 | else 265 | destImage = rotate(0) 266 | end 267 | #p "ImageList.auto_orient set " 268 | destImage.orientation = 1 269 | destImage 270 | end 271 | 272 | def setParentImages(images) 273 | @images.push(images) 274 | @images.flatten! 275 | end 276 | 277 | # Set parent orientation 278 | # 279 | # @param [Image] parent image. 280 | def setParentOrientation(img) 281 | @image.setParentOrientation(img) 282 | end 283 | 284 | def getPath 285 | @image.gen 286 | end 287 | 288 | def write(path) 289 | if path.split('.')[-1] == 'gif' 290 | # p @frames.length 291 | if @frames.length > 0 292 | # 複数のImageからblobを取り出し、これをgifとして保存する。 293 | blobs = [] 294 | if(@fRealFile) 295 | blobs.push(@image.to_blob) 296 | end 297 | @frames.each do|imglist| 298 | blobs.push(imglist.to_blob) 299 | end 300 | # p blobs.length 301 | Mrmagick::Capi.write_gif(path, blobs) 302 | else 303 | @image.write(path) 304 | end 305 | else 306 | if(@fRealFile) 307 | @image.write(path) 308 | else 309 | blobs = [] 310 | @frames.each do|imglist| 311 | blobs.push(imglist.to_blob) 312 | end 313 | if(blobs.length > 0) 314 | Mrmagick::Capi.write_gif(path, blobs) 315 | else 316 | @image.write(path) 317 | end 318 | end 319 | end 320 | end 321 | 322 | def to_blob 323 | @image.to_blob 324 | end 325 | 326 | def from_blob(blob) 327 | @image.from_blob(blob) 328 | end 329 | 330 | def magickCommand(cmd) 331 | # puts "magickCommand: " + cmd 332 | 333 | @images.each do|savedCmd| 334 | # puts "savedCmd: " + savedCmd 335 | @image.magickCommand(savedCmd) 336 | end 337 | @image.magickCommand(cmd) 338 | @images.push(cmd) 339 | end 340 | 341 | def magickCommand2(cmd) 342 | # puts "magickCommand2: " + cmd 343 | @image.magickCommand(cmd) 344 | @images.push(cmd) 345 | end 346 | 347 | def createVirtualImageList 348 | destImage = ImageList.new '' 349 | destImage.setParentImages(@images) 350 | destImage.setParentOrientation(@image) 351 | destImage 352 | end 353 | 354 | def blur_image(*args) 355 | param = args.join(',') 356 | destImage = createVirtualImageList 357 | srcImagePath = @image.gen 358 | destImage.magickCommand("convert #{srcImagePath} -blur #{param} #{destImage.getPath}") 359 | destImage 360 | end 361 | 362 | def scale(*args) 363 | if args.length > 1 364 | param = args.join('x') 365 | else 366 | scale = args[0] 367 | if !scale.to_s.include?('%') 368 | scale *= 100 369 | param = scale.to_s + '%' 370 | else 371 | param = scale 372 | end 373 | end 374 | destImage = createVirtualImageList 375 | srcImagePath = @image.gen 376 | destImage.magickCommand("convert #{srcImagePath} -resize #{param} #{destImage.getPath}") 377 | destImage 378 | end 379 | 380 | def rotate(rot) 381 | destImage = createVirtualImageList 382 | srcImagePath = @image.gen 383 | destImage.magickCommand("convert #{srcImagePath} -rotate #{rot} #{destImage.getPath}") 384 | destImage 385 | end 386 | 387 | def flop 388 | destImage = createVirtualImageList 389 | srcImagePath = @image.gen 390 | destImage.magickCommand("convert #{srcImagePath} -flop #{destImage.getPath}") 391 | destImage 392 | end 393 | 394 | def flip 395 | destImage = createVirtualImageList 396 | srcImagePath = @image.gen 397 | destImage.magickCommand("convert #{srcImagePath} -flip #{destImage.getPath}") 398 | destImage 399 | end 400 | 401 | def transpose 402 | destImage = createVirtualImageList 403 | srcImagePath = @image.gen 404 | destImage.magickCommand("convert #{srcImagePath} -rotate 90 #{destImage.getPath}") 405 | destImage.magickCommand2("convert #{srcImagePath} -flop #{destImage.getPath}") 406 | destImage 407 | end 408 | 409 | def transverse 410 | destImage = createVirtualImageList 411 | srcImagePath = @image.gen 412 | destImage.magickCommand("convert #{srcImagePath} -rotate 270 #{destImage.getPath}") 413 | destImage.magickCommand2("convert #{srcImagePath} -flop #{destImage.getPath}") 414 | destImage 415 | end 416 | 417 | # Crop the image. 418 | # 419 | # @param [Integer] offset_x offset x. 420 | # @param [Integer] offset_y offset y. 421 | # @param [Integer] width width. 422 | # @param [Integer] height height. 423 | # @return [Image] cropped image. 424 | def crop(offset_x, offset_y, width, height) 425 | destImage = createVirtualImageList 426 | srcImagePath = @image.gen 427 | if offset_x>0 428 | xOffSgnStr = "+" 429 | else 430 | xOffSgnStr = "-" 431 | offset_x = - offset_x 432 | end 433 | 434 | if offset_y>0 435 | yOffSgnStr = "+" 436 | else 437 | yOffSgnStr = "-" 438 | offset_y = - offset_y 439 | end 440 | destImage.magickCommand("convert #{srcImagePath} -crop #{width}x#{height}"+xOffSgnStr+"#{offset_x}"+yOffSgnStr+"#{offset_y}! #{destImage.getPath}") 441 | destImage 442 | end 443 | 444 | # Get width of the image. 445 | # 446 | # @return [Integer] width of the image. 447 | def columns 448 | @image.columns 449 | end 450 | 451 | # Get height of the image. 452 | # 453 | # @return [Integer] height of the image. 454 | def rows 455 | @image.rows 456 | end 457 | 458 | # Get format of the image. 459 | # 460 | # @return [String] format of the image. 461 | def format 462 | @image.format 463 | end 464 | 465 | def getImage 466 | @image 467 | end 468 | 469 | def push(images) 470 | @frames.push(images) 471 | end 472 | end 473 | class Draw 474 | end 475 | 476 | def self.formats(&blk) 477 | #puts "formats" 478 | h = self.capi_formats 479 | if blk then 480 | h.each {|item| 481 | blk.call(item) 482 | } 483 | else 484 | return h 485 | end 486 | end 487 | end 488 | -------------------------------------------------------------------------------- /mruby-mrmagick.gem: -------------------------------------------------------------------------------- 1 | name: mruby-mrmagick 2 | description: ImageMagick binding for mruby. 3 | author: Junichi Kajiwara 4 | website: https://github.com/kjunichi/mruby-mrmagick 5 | protocol: git 6 | repository: https://github.com/kjunichi/mruby-mrmagick.git 7 | dependencies: 8 | - mruby-array-ext 9 | - mruby-print 10 | -------------------------------------------------------------------------------- /src/dummy_exif.h: -------------------------------------------------------------------------------- 1 | static unsigned char dexifData[] = { 2 | 69, 120, 105, 102, 0, 0, 77, 77, 0, 42, 0, 0, 0, 8, 0, 9, 1, 15, 0, 2, 0, 3 | 0, 0, 6, 0, 0, 0, 122, 1, 16, 0, 2, 0, 0, 0, 15, 0, 0, 0, 128, 1, 18, 4 | 0, 3, 0, 0, 0, 1, 0, 3, 0, 0, 1, 26, 0, 5, 0, 0, 0, 1, 0, 0, 0, 5 | 144, 1, 27, 0, 5, 0, 0, 0, 1, 0, 0, 0, 152, 1, 40, 0, 3, 0, 0, 0, 1, 6 | 0, 1, 0, 0, 1, 50, 0, 2, 0, 0, 0, 20, 0, 0, 0, 160, 2, 19, 0, 3, 0, 7 | 0, 0, 1, 0, 1, 0, 0, 135, 105, 0, 4, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 8 | 5, 140, 109, 114, 117, 98, 121, 0, 109, 114, 117, 98, 121, 45, 109, 114, 109, 97, 103, 105, 99, 9 | 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 50, 48, 10 | 49, 53, 58, 48, 54, 58, 49, 48, 32, 49, 55, 58, 52, 54, 58, 48, 55, 0, 0, 27, 130, 11 | 154, 0, 5, 0, 0, 0, 1, 0, 0, 1, 254, 130, 157, 0, 5, 0, 0, 0, 1, 0, 0, 12 | 2, 6, 136, 34, 0, 3, 0, 0, 0, 1, 0, 2, 0, 0, 136, 39, 0, 3, 0, 0, 0, 13 | 1, 1, 64, 0, 0, 144, 0, 0, 7, 0, 0, 0, 4, 48, 50, 50, 49, 144, 4, 0, 2, 14 | 0, 0, 0, 20, 0, 0, 2, 14, 145, 1, 0, 7, 0, 0, 0, 4, 1, 2, 3, 0, 146, 15 | 1, 0, 10, 0, 0, 0, 1, 0, 0, 2, 34, 146, 2, 0, 5, 0, 0, 0, 1, 0, 0, 16 | 2, 42, 146, 3, 0, 10, 0, 0, 0, 1, 0, 0, 2, 50, 146, 4, 0, 10, 0, 0, 0, 17 | 1, 0, 0, 2, 58, 146, 7, 0, 3, 0, 0, 0, 1, 0, 5, 0, 0, 146, 10, 0, 5, 18 | 0, 0, 0, 1, 0, 0, 2, 66, 146, 20, 0, 3, 0, 0, 0, 4, 0, 0, 2, 74, 146, 19 | 124, 0, 7, 0, 0, 3, 58, 0, 0, 2, 82, 146, 145, 0, 2, 0, 0, 0, 4, 54, 55, 20 | 49, 0, 146, 146, 0, 2, 0, 0, 0, 4, 54, 55, 49, 0, 160, 0, 0, 7, 0, 0, 0, 21 | 4, 48, 49, 48, 48, 160, 1, 0, 3, 0, 0, 0, 1, 0, 1, 0, 0, 160, 2, 0, 4, 22 | 0, 0, 0, 1, 0, 0, 12, 192, 160, 3, 0, 4, 0, 0, 0, 1, 0, 0, 9, 144, 162, 23 | 23, 0, 3, 0, 0, 0, 1, 0, 2, 0, 0, 163, 1, 0, 7, 0, 0, 0, 1, 1, 0, 24 | 0, 0, 164, 2, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 164, 3, 0, 3, 0, 0, 0, 25 | 1, 0, 0, 0, 0, 164, 5, 0, 3, 0, 0, 0, 1, 0, 29, 0, 0, 164, 6, 0, 3, 26 | 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 27 | 0, 0, 11, 0, 0, 0, 5, 50, 48, 49, 53, 58, 48, 54, 58, 49, 48, 32, 49, 55, 58, 28 | 52, 54, 58, 48, 55, 0, 0, 0, 14, 151, 0, 0, 3, 143, 0, 0, 31, 47, 0, 0, 13, 29 | 181, 0, 0, 11, 15, 0, 0, 23, 49, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 83, 30 | 0, 0, 0, 20, 6, 95, 4, 199, 7, 3, 4, 53, 65, 112, 112, 108, 101, 32, 105, 79, 83, 31 | 0, 0, 1, 77, 77, 0, 10, 0, 1, 0, 9, 0, 0, 0, 1, 0, 0, 0, 2, 0, 2, 32 | 0, 7, 0, 0, 2, 46, 0, 0, 0, 140, 0, 3, 0, 7, 0, 0, 0, 104, 0, 0, 2, 33 | 186, 0, 4, 0, 9, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, 0, 9, 0, 0, 0, 1, 34 | 0, 0, 0, 214, 0, 6, 0, 9, 0, 0, 0, 1, 0, 0, 0, 212, 0, 7, 0, 9, 0, 35 | 0, 0, 1, 0, 0, 0, 1, 0, 8, 0, 10, 0, 0, 0, 3, 0, 0, 3, 34, 0, 9, 36 | 0, 9, 0, 0, 0, 1, 0, 0, 1, 19, 0, 14, 0, 9, 0, 0, 0, 1, 0, 0, 0, 37 | 1, 0, 0, 0, 0, 98, 112, 108, 105, 115, 116, 48, 48, 79, 17, 2, 0, 198, 1, 192, 1, 38 | 220, 1, 194, 1, 204, 1, 184, 1, 185, 1, 183, 1, 199, 1, 186, 1, 215, 1, 212, 1, 229, 39 | 1, 224, 1, 219, 1, 236, 1, 129, 1, 140, 1, 174, 1, 180, 1, 200, 1, 178, 1, 193, 1, 40 | 215, 1, 210, 1, 225, 1, 230, 1, 229, 1, 238, 1, 220, 1, 219, 1, 240, 1, 120, 1, 111, 41 | 1, 113, 1, 114, 1, 139, 1, 173, 1, 222, 1, 228, 1, 237, 1, 239, 1, 249, 1, 244, 1, 42 | 248, 1, 242, 1, 12, 2, 252, 1, 107, 1, 100, 1, 94, 1, 104, 1, 109, 1, 102, 1, 114, 43 | 1, 141, 1, 196, 1, 202, 1, 246, 1, 5, 2, 253, 1, 39, 2, 21, 2, 13, 2, 187, 0, 44 | 223, 0, 27, 1, 46, 1, 76, 1, 78, 1, 81, 1, 75, 1, 34, 1, 35, 1, 113, 1, 198, 45 | 1, 252, 1, 31, 2, 56, 2, 46, 2, 166, 0, 169, 0, 167, 0, 197, 0, 177, 0, 206, 0, 46 | 3, 1, 247, 0, 7, 1, 58, 1, 75, 1, 38, 1, 62, 1, 145, 1, 10, 2, 71, 2, 113, 47 | 0, 118, 0, 130, 0, 217, 0, 160, 0, 110, 0, 91, 0, 101, 0, 138, 0, 193, 0, 234, 0, 48 | 6, 1, 21, 1, 37, 1, 72, 1, 150, 1, 89, 0, 92, 0, 161, 0, 126, 0, 177, 0, 156, 49 | 0, 93, 0, 98, 0, 110, 0, 118, 0, 121, 0, 143, 0, 189, 0, 251, 0, 45, 1, 94, 1, 50 | 202, 0, 186, 0, 163, 0, 108, 0, 96, 0, 90, 0, 60, 0, 47, 0, 47, 0, 78, 0, 110, 51 | 0, 113, 0, 123, 0, 140, 0, 151, 0, 162, 0, 248, 1, 245, 1, 168, 0, 74, 1, 224, 1, 52 | 151, 1, 51, 0, 51, 0, 25, 0, 21, 0, 140, 0, 85, 0, 82, 0, 125, 0, 160, 0, 150, 53 | 0, 53, 0, 54, 0, 103, 0, 65, 0, 108, 0, 159, 0, 74, 0, 52, 0, 34, 0, 32, 0, 54 | 137, 0, 136, 0, 172, 0, 154, 0, 187, 0, 98, 1, 59, 0, 43, 0, 53, 0, 41, 0, 43, 55 | 0, 43, 0, 67, 0, 70, 0, 34, 0, 39, 0, 48, 0, 39, 0, 69, 0, 57, 0, 64, 0, 56 | 52, 0, 32, 0, 33, 0, 33, 0, 31, 0, 28, 0, 39, 0, 60, 0, 62, 0, 46, 0, 26, 57 | 0, 39, 0, 36, 0, 33, 0, 53, 0, 41, 0, 43, 0, 43, 0, 45, 0, 45, 0, 45, 0, 58 | 46, 0, 40, 0, 36, 0, 47, 0, 63, 0, 36, 0, 42, 0, 43, 0, 52, 0, 60, 0, 63, 59 | 0, 47, 0, 55, 0, 61, 0, 64, 0, 68, 0, 69, 0, 69, 0, 62, 0, 58, 0, 75, 0, 60 | 54, 0, 74, 0, 86, 0, 155, 0, 255, 0, 25, 1, 231, 0, 98, 0, 145, 0, 220, 0, 98, 61 | 1, 242, 1, 2, 2, 162, 1, 68, 1, 56, 1, 189, 1, 210, 1, 149, 1, 226, 1, 242, 1, 62 | 100, 1, 115, 1, 0, 8, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 63 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 12, 98, 112, 108, 105, 64 | 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 8, 85, 102, 108, 97, 103, 115, 85, 118, 65 | 97, 108, 117, 101, 85, 101, 112, 111, 99, 104, 89, 116, 105, 109, 101, 115, 99, 97, 108, 101, 16, 66 | 1, 19, 0, 2, 27, 237, 30, 128, 67, 135, 16, 0, 18, 59, 154, 202, 0, 8, 17, 23, 29, 67 | 35, 45, 47, 56, 58, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 9, 68 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 7, 205, 0, 69 | 0, 7, 241, 255, 255, 254, 165, 0, 0, 82, 140, 255, 255, 251, 99, 0, 0, 25, 183, 0, 4, 70 | 1, 3, 0, 3, 0, 0, 0, 1, 0, 6, 0, 0, 1, 26, 0, 5, 0, 0, 0, 1, 0, 71 | 0, 5, 194, 1, 27, 0, 5, 0, 0, 0, 1, 0, 0, 5, 202, 1, 40, 0, 3, 0, 0, 72 | 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 73 | 0, 0, 0, 0, 1}; 74 | static const int dexifDataLength = 1496; 75 | -------------------------------------------------------------------------------- /src/mrb_mrmagick.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** mrb_mrmagick.c - Mrmagick class 3 | ** 4 | ** Copyright (c) Junichi Kajiwara 2015 5 | ** 6 | ** See Copyright Notice in LICENSE 7 | */ 8 | #include 9 | #include 10 | 11 | #include "mruby.h" 12 | #include "mruby/array.h" 13 | #include "mruby/data.h" 14 | #include "mruby/string.h" 15 | #include "mrb_mrmagick.h" 16 | 17 | extern void 18 | myputs(); 19 | extern void 20 | myInitializeMagick(); 21 | extern void 22 | scale(const char *src_path, const char *dst_path, const char *ratio); 23 | extern void 24 | blur(const char *src_path, const char *dst_path, const double radius, const double sigma); 25 | extern mrb_value 26 | mrb_mrmagick_write(mrb_state *mrb, mrb_value self); 27 | extern mrb_value 28 | mrb_mrmagick_write_gif(mrb_state *mrb, mrb_value self); 29 | extern mrb_value 30 | mrb_mrmagick_get_exif_by_entry(mrb_state *mrb, mrb_value self); 31 | extern mrb_value 32 | mrb_mrmagick_to_blob(mrb_state *mrb, mrb_value self); 33 | extern mrb_value 34 | mrb_mrmagick_from_blob(mrb_state *mrb, mrb_value self); 35 | extern mrb_value 36 | mrb_mrmagick_get_columns(mrb_state *mrb, mrb_value self); 37 | extern mrb_value 38 | mrb_mrmagick_get_rows(mrb_state *mrb, mrb_value self); 39 | extern mrb_value 40 | mrb_mrmagick_get_format(mrb_state *mrb, mrb_value self); 41 | extern mrb_value 42 | mrb_mrmagick_formats(mrb_state *mrb, mrb_value self); 43 | 44 | #define DONE mrb_gc_arena_restore(mrb, 0); 45 | 46 | typedef struct { 47 | char *str; 48 | int len; 49 | } mrb_mrmagick_data; 50 | 51 | static const struct mrb_data_type mrb_mrmagick_data_type = { 52 | "mrb_mrmagick_data", mrb_free, 53 | }; 54 | 55 | /* 56 | static mrb_value 57 | mrb_mrmagick_init(mrb_state *mrb, mrb_value self) 58 | { 59 | mrb_mrmagick_data *data; 60 | char *str; 61 | int len; 62 | 63 | data = (mrb_mrmagick_data *)DATA_PTR(self); 64 | if (data) 65 | mrb_free(mrb, data); 66 | DATA_TYPE(self) = &mrb_mrmagick_data_type; 67 | DATA_PTR(self) = NULL; 68 | 69 | mrb_get_args(mrb, "s", &str, &len); 70 | data = (mrb_mrmagick_data *)mrb_malloc(mrb, sizeof(mrb_mrmagick_data)); 71 | data->str = str; 72 | data->len = len; 73 | DATA_PTR(self) = data; 74 | 75 | return self; 76 | }*/ 77 | 78 | static mrb_value 79 | mrb_mrmagick_scale(mrb_state *mrb, mrb_value self) 80 | { 81 | char *src_path, *dst_path, *ratio; 82 | 83 | mrb_get_args(mrb, "zzz", &src_path, &dst_path, &ratio); 84 | scale(src_path, dst_path, ratio); 85 | return mrb_str_new_cstr(mrb, "hi!!"); 86 | } 87 | 88 | static mrb_value 89 | mrb_mrmagick_blur(mrb_state *mrb, mrb_value self) 90 | { 91 | char *src_path, *dst_path; 92 | mrb_float radius, sigma; 93 | 94 | mrb_get_args(mrb, "zzff", &src_path, &dst_path, &radius, &sigma); 95 | blur(src_path, dst_path, (double)radius, (double)sigma); 96 | return mrb_str_new_cstr(mrb, "hi!!"); 97 | } 98 | 99 | static mrb_value 100 | mrb_mrmagick_rm(mrb_state *mrb, mrb_value self) 101 | { 102 | mrb_value ary, val; 103 | 104 | int num_files, i; 105 | char filepath[1024]; 106 | 107 | mrb_get_args(mrb, "A", &ary); 108 | num_files = RARRAY_LEN(ary); 109 | 110 | for (i = 0; i < num_files; ++i) { 111 | val = mrb_ary_ref(mrb, ary, i); 112 | strncpy(filepath, RSTRING_PTR(val), RSTRING_LEN(val)); 113 | filepath[RSTRING_LEN(val)] = '\0'; 114 | 115 | remove(filepath); 116 | } 117 | return mrb_str_new_cstr(mrb, "hi!!"); 118 | } 119 | 120 | void 121 | mrb_mruby_mrmagick_gem_init(mrb_state *mrb) 122 | { 123 | struct RClass *mrmagick_module; 124 | struct RClass *mrmagick; 125 | 126 | myInitializeMagick(); 127 | 128 | mrmagick_module = mrb_define_module(mrb, "Mrmagick"); 129 | 130 | mrb_define_module_function(mrb, mrmagick_module, "capi_formats", mrb_mrmagick_formats, MRB_ARGS_NONE()); 131 | mrmagick = mrb_define_class_under(mrb, mrmagick_module, "Capi", mrb->object_class); 132 | 133 | /*mrb_define_method(mrb, mrmagick, "initialize", mrb_mrmagick_init, MRB_ARGS_REQ(1));*/ 134 | mrb_define_class_method(mrb, mrmagick, "scale", mrb_mrmagick_scale, MRB_ARGS_REQ(3)); 135 | mrb_define_class_method(mrb, mrmagick, "blur", mrb_mrmagick_blur, MRB_ARGS_REQ(4)); 136 | mrb_define_class_method(mrb, mrmagick, "rm", mrb_mrmagick_rm, MRB_ARGS_REQ(1)); 137 | mrb_define_class_method(mrb, mrmagick, "write", mrb_mrmagick_write, MRB_ARGS_REQ(1)); 138 | mrb_define_class_method(mrb, mrmagick, "write_gif", mrb_mrmagick_write_gif, MRB_ARGS_REQ(1)); 139 | mrb_define_class_method(mrb, mrmagick, "to_blob", mrb_mrmagick_to_blob, MRB_ARGS_REQ(1)); 140 | mrb_define_class_method(mrb, mrmagick, "get_exif_by_entry", mrb_mrmagick_get_exif_by_entry, 141 | MRB_ARGS_REQ(1)); 142 | mrb_define_class_method(mrb, mrmagick, "get_columns", mrb_mrmagick_get_columns, MRB_ARGS_REQ(1)); 143 | mrb_define_class_method(mrb, mrmagick, "get_rows", mrb_mrmagick_get_rows, MRB_ARGS_REQ(1)); 144 | mrb_define_class_method(mrb, mrmagick, "get_format", mrb_mrmagick_get_format, MRB_ARGS_REQ(1)); 145 | DONE; 146 | } 147 | 148 | void 149 | mrb_mruby_mrmagick_gem_final(mrb_state *mrb) 150 | { 151 | } 152 | -------------------------------------------------------------------------------- /src/mrb_mrmagick.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** mrb_mrmagick.h - Mrmagick class 3 | ** 4 | ** See Copyright Notice in LICENSE 5 | */ 6 | 7 | #ifndef MRB_MRMAGICK_H 8 | #define MRB_MRMAGICK_H 9 | 10 | void 11 | mrb_mruby_mrmagick_gem_init(mrb_state *mrb); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/util.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "mruby.h" 6 | #include "mruby/array.h" 7 | #include "mruby/data.h" 8 | #include "mruby/hash.h" 9 | #include "mruby/string.h" 10 | #include "mruby/variable.h" 11 | 12 | #include "dummy_exif.h" 13 | 14 | using namespace std; 15 | using namespace Magick; 16 | 17 | extern "C" void 18 | myInitializeMagick() 19 | { 20 | InitializeMagick("."); 21 | } 22 | 23 | static void 24 | getSrcImageFilePath(mrb_state *mrb, mrb_value obj, string *path) 25 | { 26 | mrb_value val = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@parentPath")); 27 | string filepath(RSTRING_PTR(val), RSTRING_LEN(val)); 28 | *path = filepath; 29 | } 30 | 31 | extern "C" void 32 | scale(const char *srcPath, const char *destPath, const char *ratio) 33 | { 34 | Image image; 35 | image.read(srcPath); 36 | // calc geom. 37 | image.scale(ratio); 38 | image.write(destPath); 39 | } 40 | 41 | extern "C" void 42 | blur(const char *srcPath, const char *destPath, const double radius, const double sigma) 43 | { 44 | Image image; 45 | image.read(srcPath); 46 | // calc geom. 47 | image.blur(radius, sigma); 48 | image.write(destPath); 49 | } 50 | extern "C" mrb_value 51 | mrb_mrmagick_get_exif_by_entry(mrb_state *mrb, mrb_value self) 52 | { 53 | string srcImageFilePath; 54 | 55 | mrb_value obj, val; 56 | 57 | mrb_get_args(mrb, "o", &obj); 58 | 59 | val = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@exifKey")); 60 | string tmpstr(RSTRING_PTR(val), RSTRING_LEN(val)); 61 | string exiftag = "EXIF:" + tmpstr; 62 | getSrcImageFilePath(mrb, obj, &srcImageFilePath); 63 | Image img; 64 | img.read(srcImageFilePath.c_str()); 65 | string exifStr = img.attribute(exiftag); 66 | 67 | const char *cstr = exifStr.c_str(); 68 | 69 | return mrb_str_new_cstr(mrb, cstr); 70 | } 71 | 72 | static void 73 | writeAndBlob(Image *img, mrb_state *mrb, mrb_value obj) 74 | { 75 | string srcImageFilePath; 76 | mrb_value isBlob = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@isBlob")); 77 | 78 | if(mrb_bool(isBlob)) { 79 | // read image from blob 80 | mrb_value mrbBlob = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@blob")); 81 | 82 | Blob blob(RSTRING_PTR(mrbBlob), RSTRING_LEN(mrbBlob)); 83 | img->read(blob); 84 | } else { 85 | // read image from file. 86 | getSrcImageFilePath(mrb, obj, &srcImageFilePath); 87 | 88 | img->read(srcImageFilePath.c_str()); 89 | } 90 | mrb_value ov = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@orientationv")); 91 | if (mrb_fixnum_p(ov)) { 92 | if(img->orientation() == 0) { 93 | Blob exifdata(dexifData, dexifDataLength); 94 | img->profile("exif", exifdata); 95 | } 96 | int orientation = mrb_fixnum(ov); 97 | switch (orientation) { 98 | case 1: 99 | img->orientation(TopLeftOrientation); 100 | img->attribute("EXIF:Orientation", "1"); 101 | break; 102 | case 2: 103 | img->orientation(TopRightOrientation); 104 | img->attribute("EXIF:Orientation", "2"); 105 | break; 106 | case 3: 107 | img->orientation(BottomRightOrientation); 108 | img->attribute("EXIF:Orientation", "3"); 109 | break; 110 | case 4: 111 | img->orientation(BottomLeftOrientation); 112 | img->attribute("EXIF:Orientation", "4"); 113 | break; 114 | case 5: 115 | img->orientation(LeftTopOrientation); 116 | img->attribute("EXIF:Orientation", "5"); 117 | break; 118 | case 6: 119 | img->orientation(RightTopOrientation); 120 | img->attribute("EXIF:Orientation", "6"); 121 | break; 122 | case 7: 123 | img->orientation(RightBottomOrientation); 124 | img->attribute("EXIF:Orientation", "7"); 125 | break; 126 | case 8: 127 | img->orientation(LeftBottomOrientation); 128 | img->attribute("EXIF:Orientation", "8"); 129 | break; 130 | default: 131 | break; 132 | } 133 | } 134 | // exif処理 135 | // ハッシュに登録されている項目を書き込む 136 | mrb_value exifObj = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@exif")); 137 | if (mrb_hash_p(exifObj)) { 138 | mrb_value keys = mrb_hash_keys(mrb, exifObj); 139 | int len = RARRAY_LEN(keys); 140 | 141 | for (int i = 0; i < len; i++) { 142 | mrb_value key = mrb_ary_ref(mrb, keys, i); 143 | mrb_value ev = mrb_hash_get(mrb, exifObj, key); 144 | string exifValue(RSTRING_PTR(ev), RSTRING_LEN(ev)); 145 | string exiftag = "EXIF:"; 146 | exiftag.append(RSTRING_PTR(key), RSTRING_LEN(key)); 147 | 148 | img->attribute(exiftag, exifValue); 149 | } 150 | } 151 | /* 152 | # これまでのコマンドを実行する。 153 | */ 154 | mrb_value val = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@cmd")); 155 | if (mrb_nil_p(val)) { 156 | return; 157 | } 158 | int idx = 0; 159 | 160 | // for c in @cmd do 161 | int num_cmds = RARRAY_LEN(val); 162 | for (int i = 0; i < num_cmds; ++i) { 163 | mrb_value c = mrb_ary_ref(mrb, val, i); 164 | mrb_value params = mrb_funcall(mrb, c, "split", 1, mrb_str_new_cstr(mrb, " ")); 165 | mrb_value v = mrb_funcall(mrb, c, "include?", 1, mrb_str_new_cstr(mrb, "-resize")); 166 | if (mrb_bool(v)) { 167 | // Mrmagick::Capi.scale(params[1], params[4], params[3]) 168 | v = mrb_ary_ref(mrb, params, 3); 169 | string scalestr(RSTRING_PTR(v), RSTRING_LEN(v)); 170 | img->scale(scalestr.c_str()); 171 | } 172 | v = mrb_funcall(mrb, c, "include?", 1, mrb_str_new_cstr(mrb, "-blur")); 173 | if (mrb_bool(v)) { 174 | // radius_sigma=params[3].split(",") 175 | mrb_value params_3 = mrb_ary_ref(mrb, params, 3); 176 | mrb_value radius_sigma = mrb_funcall(mrb, params_3, "split", 1, mrb_str_new_cstr(mrb, ",")); 177 | v = mrb_funcall(mrb, radius_sigma, "length", 0); 178 | float sigma = 0.5; 179 | if (mrb_fixnum(v) >= 2) { 180 | mrb_value radius_sigma_1 = mrb_ary_ref(mrb, radius_sigma, 1); 181 | v = mrb_funcall(mrb, radius_sigma_1, "to_f", 0); 182 | sigma = mrb_float(v); 183 | } 184 | v = mrb_funcall(mrb, mrb_ary_ref(mrb, radius_sigma, 0), "to_f", 0); 185 | float radius = mrb_float(v); 186 | img->blur(radius, sigma); 187 | } 188 | v = mrb_funcall(mrb, c, "include?", 1, mrb_str_new_cstr(mrb, "-rotate")); 189 | if (mrb_bool(v)) { 190 | v = mrb_ary_ref(mrb, params, 3); 191 | v = mrb_funcall(mrb, v, "to_f", 0); 192 | float rot = mrb_float(v); 193 | img->rotate((double)rot); 194 | img->page("0x0+0+0"); 195 | } 196 | v = mrb_funcall(mrb, c, "include?", 1, mrb_str_new_cstr(mrb, "-flop")); 197 | if (mrb_bool(v)) { 198 | img->flop(); 199 | } 200 | v = mrb_funcall(mrb, c, "include?", 1, mrb_str_new_cstr(mrb, "-flip")); 201 | if (mrb_bool(v)) { 202 | img->flip(); 203 | } 204 | v = mrb_funcall(mrb, c, "include?", 1, mrb_str_new_cstr(mrb, "-crop")); 205 | if (mrb_bool(v)) { 206 | v = mrb_ary_ref(mrb, params, 3); 207 | Geometry geom(string(RSTRING_PTR(v), RSTRING_LEN(v))); 208 | geom.aspect(false); 209 | img->crop(geom); 210 | img->page("0x0+0+0"); 211 | } 212 | ++idx; 213 | } 214 | } 215 | 216 | extern "C" mrb_value 217 | mrb_mrmagick_write(mrb_state *mrb, mrb_value self) 218 | { 219 | Image img; 220 | 221 | mrb_value obj; 222 | 223 | mrb_get_args(mrb, "o", &obj); 224 | 225 | mrb_value val = mrb_iv_get(mrb, obj, mrb_intern_lit(mrb, "@outpath")); 226 | string distImageFilePath(RSTRING_PTR(val), RSTRING_LEN(val)); 227 | 228 | writeAndBlob(&img, mrb, obj); 229 | 230 | img.write(distImageFilePath.c_str()); 231 | return mrb_nil_value(); 232 | } 233 | 234 | /** 235 | ファイルパスとBlobの配列を受け取り、gif animationとして書き出す 236 | */ 237 | extern "C" mrb_value 238 | mrb_mrmagick_write_gif(mrb_state *mrb, mrb_value self) 239 | { 240 | mrb_value obj; 241 | char *path = NULL; 242 | 243 | // get gif file name to write. 244 | mrb_get_args(mrb, "zo", &path, &obj); 245 | if (mrb_array_p(obj)) { 246 | list ilist; 247 | 248 | int len = RARRAY_LEN(obj); 249 | for (int i = 0; i < len; i++) { 250 | Blob blob(RSTRING_PTR(mrb_ary_ref(mrb, obj, i)), RSTRING_LEN(mrb_ary_ref(mrb, obj, i))); 251 | Image img(blob); 252 | img.animationDelay(10); 253 | img.animationIterations(0); 254 | ilist.push_back(img); 255 | } 256 | Image appended; 257 | writeImages(ilist.begin(), ilist.end(), path); 258 | } 259 | return mrb_nil_value(); 260 | } 261 | 262 | extern "C" mrb_value 263 | mrb_mrmagick_to_blob(mrb_state *mrb, mrb_value self) 264 | { 265 | mrb_value obj; 266 | 267 | mrb_get_args(mrb, "o", &obj); 268 | 269 | Image img; 270 | writeAndBlob(&img, mrb, obj); 271 | 272 | Blob blob; 273 | img.write(&blob); 274 | 275 | mrb_value val; 276 | val = mrb_str_new(mrb, (const char *)blob.data(), blob.length()); 277 | return val; 278 | } 279 | 280 | /* 281 | * Return width of the image. 282 | */ 283 | extern "C" mrb_value 284 | mrb_mrmagick_get_columns(mrb_state *mrb, mrb_value self) 285 | { 286 | mrb_value obj; 287 | mrb_get_args(mrb, "o", &obj); 288 | 289 | Image img; 290 | writeAndBlob(&img, mrb, obj); 291 | Blob blob; 292 | img.write(&blob); 293 | return mrb_fixnum_value((int)img.columns()); 294 | } 295 | 296 | /* 297 | * Return height of the image. 298 | * 299 | * @param [Image] image. 300 | */ 301 | extern "C" mrb_value 302 | mrb_mrmagick_get_rows(mrb_state *mrb, mrb_value self) 303 | { 304 | mrb_value obj; 305 | mrb_get_args(mrb, "o", &obj); 306 | 307 | Image img; 308 | writeAndBlob(&img, mrb, obj); 309 | Blob blob; 310 | img.write(&blob); 311 | return mrb_fixnum_value((int)img.rows()); 312 | } 313 | 314 | /* 315 | * Return format of the image. 316 | * 317 | * @param [Image] image. 318 | */ 319 | extern "C" mrb_value 320 | mrb_mrmagick_get_format(mrb_state *mrb, mrb_value self) 321 | { 322 | mrb_value obj; 323 | mrb_get_args(mrb, "o", &obj); 324 | 325 | Image img; 326 | writeAndBlob(&img, mrb, obj); 327 | Blob blob; 328 | img.write(&blob); 329 | string format = img.format(); 330 | return mrb_str_new(mrb, format.c_str(), format.length()); 331 | } 332 | 333 | /* 334 | * Return imagemagick's support format list. 335 | * 336 | */ 337 | extern "C" mrb_value 338 | mrb_mrmagick_formats(mrb_state *mrb, mrb_value self) 339 | { 340 | string str; 341 | mrb_value table = mrb_hash_new(mrb); 342 | 343 | list coderList; 344 | coderInfoList( &coderList, // Reference to output list 345 | CoderInfo::TrueMatch, // Match readable formats 346 | CoderInfo::AnyMatch, // Don't care about writable formats 347 | CoderInfo::AnyMatch); // Don't care about multi-frame support 348 | list::iterator entry = coderList.begin(); 349 | while(entry != coderList.end()) 350 | { 351 | // B is "*" if the format has native blob support, and "-" otherwise. 352 | // R is "r" if ImageMagick can read the format, and "-" otherwise. 353 | // W is "w" if ImageMagick can write the format, and "-" otherwise. 354 | // A is "+" if the format supports multi-image files, and "-" otherwise. 355 | 356 | 357 | string keystr = entry->name(); 358 | mrb_value key = mrb_str_new(mrb, keystr.c_str(), keystr.length()); 359 | 360 | //str += "=>"; 361 | 362 | //str += entry->description(); 363 | //str += "Readable = "; 364 | str = "*"; 365 | if ( entry->isReadable() ) 366 | str += "r"; 367 | else 368 | str += "-"; 369 | //str += "Writable = "; 370 | if ( entry->isWritable() ) 371 | str += "w"; 372 | else 373 | str += "-"; 374 | //str += ", "; 375 | //str += "Multiframe = "; 376 | if ( entry->isMultiFrame() ) 377 | str += "+"; 378 | else 379 | str += "-"; 380 | //str += "\n"; 381 | 382 | entry ++; 383 | mrb_value val = mrb_str_new(mrb, str.c_str(), str.length()); 384 | mrb_hash_set(mrb, table, key, val); 385 | } 386 | //mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "table"), table); 387 | return table; 388 | } 389 | -------------------------------------------------------------------------------- /test/mrb_mrmagick.rb: -------------------------------------------------------------------------------- 1 | ## 2 | ## Mrmagick Test 3 | ## 4 | def setupTestImage 5 | `convert -size "640x480" -background "#C0C0C0" -fill "#FFFF00" caption:"ABC" output.png` 6 | end 7 | 8 | def tearDownTestImage 9 | `rm -f t.png dest.png dest*.gif diff.png output.png` 10 | end 11 | 12 | assert('Mrmagick::Image#scale') do 13 | setupTestImage 14 | Mrmagick::ImageList.new('output.png').scale(0.5).write('t.png') 15 | `convert -scale 50% output.png dest.png` 16 | `composite -compose difference dest.png t.png diff.png` 17 | t = `identify -format "%[mean]" diff.png` 18 | t.gsub!("\n","") 19 | assert_equal('0', t) 20 | tearDownTestImage 21 | end 22 | 23 | assert('Mrmagick::Image#blur_image') do 24 | setupTestImage 25 | Mrmagick::ImageList.new('output.png').blur_image(1.0, 8.0).write('t.png') 26 | `convert -blur 1.0x8.0 output.png dest.png` 27 | `composite -compose difference dest.png t.png diff.png` 28 | t = `identify -format "%[mean]" diff.png` 29 | t.gsub!("\n","") 30 | assert_equal('0', t) 31 | tearDownTestImage 32 | end 33 | 34 | assert('Mrmagick::Image#rotate') do 35 | setupTestImage 36 | Mrmagick::ImageList.new('output.png').rotate(30).write('t.png') 37 | `convert -rotate 30 output.png dest.png` 38 | `composite -compose difference dest*.png t.png diff.png` 39 | t = `identify -format "%[mean]" diff.png` 40 | t.gsub!("\n","") 41 | assert_equal('0', t) 42 | tearDownTestImage 43 | end 44 | 45 | assert('Mrmagick::Image#flop') do 46 | setupTestImage 47 | Mrmagick::ImageList.new('output.png').flop.write('t.png') 48 | `convert -flop output.png dest.png` 49 | `composite -compose difference dest.png t.png diff.png` 50 | t = `identify -format "%[mean]" diff.png` 51 | t.gsub!("\n","") 52 | assert_equal('0', t) 53 | tearDownTestImage 54 | end 55 | 56 | assert('Mrmagick::Image#flip') do 57 | setupTestImage 58 | Mrmagick::ImageList.new('output.png').flip.write('t.png') 59 | `convert -flip output.png dest.png` 60 | `composite -compose difference dest.png t.png diff.png` 61 | t = `identify -format "%[mean]" diff.png` 62 | t.gsub!("\n","") 63 | assert_equal('0', t) 64 | tearDownTestImage 65 | end 66 | 67 | assert('Mrmagick::Image#orientation') do 68 | setupTestImage 69 | o = Mrmagick::ImageList.new('output.png').orientation 70 | assert_equal('', o) 71 | t = Mrmagick::ImageList.new('output.png') 72 | t.orientation = 1 73 | t.write('t.png') 74 | t = Mrmagick::ImageList.new('t.png') 75 | 76 | # for ImageMagick v7 77 | result = t.orientation 78 | result = '1' if result == "" 79 | assert_equal('1', result) 80 | 81 | t = Mrmagick::ImageList.new('output.png') 82 | t.orientation = 7 83 | t.write('t.jpg') 84 | t = Mrmagick::ImageList.new('t.jpg') 85 | assert_equal('7', t.orientation) 86 | tearDownTestImage 87 | end 88 | 89 | assert('Mrmagick::Image#auto_orient') do 90 | setupTestImage 91 | o = Mrmagick::ImageList.new('output.png') 92 | o.orientation = 5 93 | o.write('t.jpg') 94 | t = Mrmagick::ImageList.new('t.jpg') 95 | t = t.auto_orient 96 | t.write('t.jpg') 97 | t2 = t.rotate(123) 98 | assert_equal('1', t2.orientation) 99 | t = Mrmagick::ImageList.new('t.jpg') 100 | assert_equal('1', t.orientation) 101 | tearDownTestImage 102 | end 103 | 104 | assert('Mrmagick::Image#write') do 105 | setupTestImage 106 | o = Mrmagick::ImageList.new('output.png') 107 | o2 = o.rotate(180) 108 | o3 = o.blur_image(1.0, 8.0) 109 | o.push o2 110 | o.push o3 111 | o.write('dest.gif') 112 | `convert +adjoin dest.gif dest.gif` 113 | `convert output.png dest.gif` 114 | `composite -compose difference dest-0.gif dest.gif diff.png` 115 | t = `identify -format "%[mean]" diff.png` 116 | t.gsub!("\n","") 117 | assert_equal('0', t) 118 | `convert -rotate 180 output.png dest.gif` 119 | `composite -compose difference dest-1.gif dest.gif diff.png` 120 | t = `identify -format "%[mean]" diff.png` 121 | t.gsub!("\n","") 122 | assert_equal('0', t) 123 | `convert -blur 1.0x8.0 output.png dest.gif` 124 | `composite -compose difference dest-2.gif dest.gif diff.png` 125 | t = `identify -format "%[mean]" diff.png` 126 | t.gsub!("\n","") 127 | 128 | # for ImageMagick v7 129 | t = "0" if t.to_f < 0.003 130 | assert_equal('0', t) 131 | 132 | tearDownTestImage 133 | end 134 | 135 | assert('Mrmagick::Image#columns') do 136 | setupTestImage 137 | o = Mrmagick::ImageList.new('output.png') 138 | assert_equal(640, o.columns) 139 | tearDownTestImage 140 | end 141 | 142 | assert("Mrmagick::Image#rows") do 143 | setupTestImage 144 | o = Mrmagick::ImageList.new('output.png') 145 | assert_equal(480, o.rows) 146 | tearDownTestImage 147 | end 148 | 149 | assert('Mrmagick::Image#format') do 150 | setupTestImage 151 | o = Mrmagick::ImageList.new('output.png') 152 | assert_equal('Portable Network Graphics', o.format) 153 | o.write('dest.gif') 154 | o = Mrmagick::ImageList.new('dest.gif') 155 | assert_equal('CompuServe graphics interchange format', o.format) 156 | tearDownTestImage 157 | end 158 | 159 | assert('Mrmagick::Image#crop') do 160 | setupTestImage 161 | Mrmagick::ImageList.new('output.png').crop(8, 16, 256, 384).write('t.png') 162 | `convert -crop 256x384+8+16! output.png dest.png` 163 | `composite -compose difference dest.png t.png diff.png` 164 | t = `identify -format "%[mean]" diff.png` 165 | t.gsub!("\n","") 166 | assert_equal('0', t) 167 | 168 | tearDownTestImage 169 | end 170 | 171 | assert("Mrmagick::ImageList#from_blob") do 172 | setupTestImage 173 | imgData = `cat output.png` 174 | p imgData.length 175 | img1 = Mrmagick::ImageList.new() 176 | img1.from_blob(imgData) 177 | img2 = Mrmagick::ImageList.new("output.png") 178 | #assert_equal(img1,img2) 179 | assert_equal(img1.rows,img2.rows) 180 | assert_equal(img1.columns,img2.columns) 181 | tearDownTestImage 182 | end 183 | 184 | assert("Mrmagick.formats") do 185 | assert_equal(true, Mrmagick.formats.has_key?("PNM")) 186 | Mrmagick.formats {|i| assert_equal(false, i.empty?)} 187 | end 188 | -------------------------------------------------------------------------------- /test/mruby_mrmagick_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "mruby.h" 3 | 4 | static mrb_value 5 | mrb_mrmagick_test_mrmagick_setup(mrb_state *mrb, mrb_value self) 6 | { 7 | return mrb_true_value(); 8 | } 9 | 10 | static mrb_value 11 | mrb_mrmagick_test_mrmagick_cleanup(mrb_state *mrb, mrb_value self) 12 | { 13 | return mrb_true_value(); 14 | } 15 | 16 | void 17 | mrb_mruby_mrmagick_gem_test(mrb_state* mrb) 18 | { 19 | struct RClass *mrmagick_test = mrb_define_module(mrb, "MRubyMrmagickTestUtil"); 20 | 21 | mrb_define_class_method(mrb, mrmagick_test, "mrmagick_test_setup", mrb_mrmagick_test_mrmagick_setup, MRB_ARGS_NONE()); 22 | mrb_define_class_method(mrb, mrmagick_test, "mrmagick_test_cleanup", mrb_mrmagick_test_mrmagick_cleanup, MRB_ARGS_NONE()); 23 | } 24 | --------------------------------------------------------------------------------