[ImageMagickラーニング]Fred's ImageMagick Scripts回転C++の統合ソリューション

5185 ワード

このような問題に遭遇したことがあります.
  • Fred's ImageMagick Scriptsが提供するスクリプトは、とても強力ですが、直接C++プログラムに呼び出されず、licenseの問題があり、C++版に翻訳できればいいです.どうやって翻訳しますか?
  • Fred's ImageMagick Scriptsで提供されるスクリプトは豊富で、「Shellスクリプト->C++コード」の翻訳中にこれらのスクリプトに対して統一的な解決策がなく、各スクリプトを特例として扱うと、その作業量は膨大です.コードの実行効率を損なわずに、翻訳の作業量を最小限に抑えるにはどうすればいいですか?

  • ImageMagickコマンドの中間操作の結果によると、答えは次のとおりです.
    Fred's ImageMagick Scriptsのメソッドに従って、convertコマンド(C++コードでConvertImageCommand()関数を複数回呼び出す)を複数回呼び出すのではなく、Fred's ImageMagick Scriptsの各特効ページの最後のテキストで説明した等価命令行を参照して、対応するコマンド行文字列を次のコードのIM_にパラメータとして渡すConvert()関数.簡単だ!
    例えば、mf-smallを除去する.jpgピクチャの背景ノイズは、mf-small-outとして保存する.jpg,TEXTCLEANERスクリプト等価コマンドラインを模写する
    convert \( $infile -colorspace gray -type grayscale -contrast-stretch 0 \) \
    \( -clone 0 -colorspace gray -negate -lat ${filtersize}x${filtersize}+${offset}% -contrast-stretch 0 \) \
    -compose copy_opacity -composite -fill "$bgcolor" -opaque none +matte \
    -deskew 40% -sharpen 0x1 $outfile
    IM_に送信Convert()関数の文字列は次のとおりです.
    convert ( mf-small.jpg -colorspace gray -type grayscale -contrast-stretch 0 ) ( -clone 0 -colorspace gray -negate -lat 25x25+10% -contrast-stretch 0 ) -compose copy_opacity -composite -fill \"white\" -opaque none +matte -deskew 40% -sharpen 0x1 mf-small-out.jpg
    サンプルコード:
    #include <wand/MagickWand.h>
    #include <string>
    #include <vector>
    #include <sstream>
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    using namespace std;
    
    void AllocArg(const char* cmd, int &argc, char** &argv) {
    	istringstream issCmd(cmd);
    	string sPara;
    	vector<string> vParas;
    
    	argc = 0;
    	while(issCmd >> sPara) {
    		vParas.push_back(sPara);
    		++argc;
    	}
    
    	argv = (char**)malloc(argc * sizeof(char*));
    	for(int i = 0; i < argc; ++i) {
    		argv[i] = (char*)malloc(vParas[i].size() + 1);
    		strcpy(argv[i], vParas[i].c_str());
    	}
    }
    
    void FreeArg(int &argc, char** &argv) {
    	if(argv != NULL) {
    		for(int i = 0; i < argc; ++i) {
    			free(argv[i]);
    		}
    		free(argv);
    		argv = NULL;
    	}
    }
    
    MagickBooleanType IM_Convert(const char* cmd) {
    	char** argv = NULL;
    	int argc = 0;
    	AllocArg(cmd, argc, argv);
    
    	ExceptionInfo *exception = NULL;
    	ImageInfo *image_info = NULL;
     	MagickBooleanType status = MagickTrue;
    
    	MagickCoreGenesis(*argv, MagickTrue);
    	exception = AcquireExceptionInfo();
    	image_info = AcquireImageInfo();
    
    	status = MagickCommandGenesis(image_info, ConvertImageCommand, argc, argv, (char **) NULL, exception);
    
    	image_info = DestroyImageInfo(image_info);
    	exception = DestroyExceptionInfo(exception);
    	MagickCoreTerminus();
    
    	FreeArg(argc, argv);
    
    	return(status);
    }
    
    int main(int argc, char* argv[])
    {
    	IM_Convert("convert ( mf-small.jpg -colorspace gray -type grayscale -contrast-stretch 0 ) "
    		"( -clone 0 -colorspace gray -negate -lat 25x25+10% -contrast-stretch 0 ) "
    		"-compose copy_opacity -composite -fill white -opaque none +matte "
    		"-deskew 40% -sharpen 0x1 mf-small-out.jpg");
    }

    Makefile:
    all:
            g++ -o im -g `pkg-config --cflags --libs MagickWand` main.cpp
    
    clean:
            rm -f im

    注意:
  • IM_へConvert()のパラメータ文字列も動的に生成される可能性があります.たとえば、中のいくつかのパラメータの取捨選択、パラメータ値の計算などです.これらの動的要因については、IM_Convert()の外側には、パラメータの取捨選択、パラメータ値の計算などに使用される関数がカプセル化され、最終的にコマンドライン文字列が動的に生成され、IM_に伝達されるConvert().デザインモードが好きな学生は、ここで特技を発揮することができます.
  • 上の動的生成コマンドライン文字列はstlのstringstreamで良いです.
  • 実際には、コマンドライン文字列を動的に生成したり、文字列を解析したり、解析したパラメータを破棄したりする余分な計算量がありますが、これらの消費はConvertImageCommand()関数自体の計算量に比べて無視できます.
  • ConvertImageCommand()関数が一時変数処理、スタックインなどの遊び方を提供している以上、私たちは自分で同じようなものを作り直す必要はありません.下から始めて、少しずつコードをほじくって、「コンパクトで高性能」なカスタム画像処理の特効関数をカスタマイズしようとしないでください.そうすれば、損をしません.
  • コマンドラインの「(」と「)」の前後にスペースが必要です.そうしないと、ImageMagickコマンドは認識されません.このハードな規定は、IMにも適用されます.Convert()は、この関数の入力文字列の「(」と「)」の前後にスペースが必要です!
  • ここでいう「統合ソリューション」は、はっきり言って、convertコマンドがConvertImageCommand(ImageInfo*image_info,int argc,char**argv,char**metadata,ExceptionInfo*exception)関数を呼び出し、私たちのプログラムもそれを呼び出します.異なるのは、前者がスクリプト用であり、後者がCプログラムに呼び出し、文字列(コマンドライン)パラメータを1つだけ入力する必要があることです.
  • ここではAndroid版のImageMagickの紹介がありますが、それぞれの特効は、Javaコード
  • を自分で書くようです.
  • 次のコマンドラインに対して、端末で直接OKを実行し、IM_Convert()を実行すると、次のエラーメッセージが表示されます.後でIM_に伝えますConvert()の文字列の「white」をwhiteに変更すればOKです.実際、コマンドラインの「white」の前後に二重引用符を付けるか持たないかは可能ですが、IM_に伝えます.Convert()の文字列には持たないでください.そうしないと、ConvertImageCommand()関数で解析するパラメータに前後の二重引用符が付いていて、ConvertImageCommand()に一致するものが見つからず、エラーが発生します.

  • IM_へConvert()のコマンドライン:
    convert ( mf-small.jpg -colorspace gray -type grayscale -contrast-stretch 0 ) ( -clone 0 -colorspace gray -negate -lat 25x25+10% -contrast-stretch 0 ) -compose copy_opacity -composite -fill \"white\" -opaque none +matte -deskew 40% -sharpen 0x1 mf-small-out.jpg
    エラーメッセージ:
    im: unable to open image `"white"': No such file or directory @ error/blob.c/OpenBlob/2641.
    im: no decode delegate for this image format `"white"' @ error/constitute.c/ReadImage/550.