1

I've been trying to find a solution to this for a long time, but I still cannot figure out how to do this.

What I need

To be able to execute a convert command (or equivalent in code) from within an OSX app, regardless of whether the user has ImageMagick (and its dependencies) installed.

What I've tried

Given that we have to cover (obviously) the case where the user doesn't already have ImageMagick installed, I assume we have to make it somehow self-contained...

Approach A : Pack the binary, plain and simple, within the bundle, and execute it with NSTask.

Working? Yes, but only on my Mac where every library is pre-installed.

Approach B : Link with the static libraries.

This is the more... obvious approach. However, there are still issues.

I first tried using these precompiled IM release + Delegates. After a lot of tweaks, I got it to work.

The thing is: it include the JPEG, PNG, TIFF delegates. But not the FreeType one which I definitely need.

So... I tried re-compiling it all from scratch AND the FreeType delegate. And here come all sorts of issues (all mostly related with libraries being missing). I mean... I link the static libraries, then see a complete list of errors... add some missing library... and then a new list of errors appear. Obviously, something is wrong.

Here's what it looks like :

Undefined symbols for architecture x86_64:
  "_FcConfigDestroy", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcFontList", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcFontSetDestroy", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcInitLoadConfigAndFonts", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcObjectSetBuild", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcObjectSetDestroy", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcPatternCreate", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcPatternDestroy", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcPatternGetInteger", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_FcPatternGetString", referenced from:
      _LoadFontConfigFonts in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-type.o)
  "_ImfCloseInputFile", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfCloseOutputFile", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfDeleteHeader", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfErrorMessage", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfFloatToHalf", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfHalfToFloat", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfHeaderDataWindow", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfHeaderDisplayWindow", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfHeaderSetCompression", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfHeaderSetDataWindow", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfHeaderSetDisplayWindow", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfHeaderSetLineOrder", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfInputHeader", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfInputReadPixels", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfInputSetFrameBuffer", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfNewHeader", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfOpenInputFile", referenced from:
      _ReadEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfOpenOutputFile", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfOutputSetFrameBuffer", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_ImfOutputWritePixels", referenced from:
      _WriteEXRImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-exr.o)
  "_cmsCloseProfile", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
      _GetImageProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
      _GetMagickProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
  "_cmsCreateTransformTHR", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_cmsDeleteTransform", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_cmsDoTransform", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_cmsGetColorSpace", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_cmsGetDeviceClass", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_cmsGetPCS", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_cmsGetProfileInfoASCII", referenced from:
      _GetImageProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
      _GetMagickProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
  "_cmsOpenProfileFromMem", referenced from:
      _GetImageProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
      _GetMagickProperty in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-property.o)
  "_cmsOpenProfileFromMemTHR", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_cmsSetLogErrorHandler", referenced from:
      _ProfileImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-profile.o)
  "_ddjvu_cache_set_size", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_context_create", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_context_release", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_document_create", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_document_get_pageinfo_imp", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_document_get_pagenum", referenced from:
      _process_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_document_job", referenced from:
      _process_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_format_create", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_format_release", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_format_set_row_order", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_format_set_y_direction", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_job_get_user_data", referenced from:
      _process_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_job_release", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_job_set_user_data", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_job_status", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_message_peek", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
      _pump_data_until_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_message_pop", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_message_wait", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_page_create_by_pageno", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_page_get_type", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_page_job", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_page_render", referenced from:
      _ReadDJVUImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_stream_close", referenced from:
      _pump_data_until_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_ddjvu_stream_write", referenced from:
      _pump_data_until_message in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-djvu.o)
  "_fftw_cleanup", referenced from:
      _ForwardFourierTransformImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
      _InverseFourierTransformImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
  "_fftw_destroy_plan", referenced from:
      _ForwardFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
      _InverseFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
  "_fftw_execute_dft_c2r", referenced from:
      _InverseFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
  "_fftw_execute_dft_r2c", referenced from:
      _ForwardFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
  "_fftw_plan_dft_c2r_2d", referenced from:
      _InverseFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
  "_fftw_plan_dft_r2c_2d", referenced from:
      _ForwardFourierTransformChannel in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-fourier.o)
  "_lzma_auto_decoder", referenced from:
      _ReadMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
  "_lzma_code", referenced from:
      _ReadMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
      _WriteMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
  "_lzma_easy_encoder", referenced from:
      _WriteMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
  "_lzma_end", referenced from:
      _ReadMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
      _WriteMIFFImage in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-miff.o)
  "_opj_create_compress", referenced from:
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_create_decompress", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_decode", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_destroy_codec", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_destroy_cstr_index", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_encode", referenced from:
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_end_compress", referenced from:
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_end_decompress", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_get_decoded_tile", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_image_create", referenced from:
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_image_destroy", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_read_header", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_set_decode_area", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_set_default_decoder_parameters", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_set_default_encoder_parameters", referenced from:
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_set_error_handler", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_set_warning_handler", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_setup_decoder", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_setup_encoder", referenced from:
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_start_compress", referenced from:
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_create", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_destroy", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_set_read_function", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_set_seek_function", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_set_skip_function", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_set_user_data", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_set_user_data_length", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_stream_set_write_function", referenced from:
      _ReadJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
      _WriteJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
  "_opj_version", referenced from:
      _RegisterJP2Image in libMagickCore-6.Q8.a(magick_libMagickCore_6_Q8_la-jp2.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Any suggestions? Have you managed to use ImageMagick from Cocoa at all?

Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
  • Off topic, but what are you doing with `convert`? In the world of Cocoa, you already have CoreImageFilters & CoreGraphics that handle the majority of features offered by IM. – emcconville Oct 18 '16 at 14:34
  • @emcconville Watermarking images (including but not limited to text). – Dr.Kameleon Oct 18 '16 at 14:52
  • 1
    If you just want to do relatively simple things like watermarking, resizing and compositing, you could use the `GD` functions in the built-in `PHP` interpreter... `/usr/bin/php -i | grep -A20 gd` and draw text with TrueType fonts http://php.net/manual/en/function.imagefttext.php – Mark Setchell Oct 18 '16 at 18:57
  • 1
    http://stackoverflow.com/a/39272442/2836621 and http://stackoverflow.com/a/35128743/2836621 – Mark Setchell Oct 18 '16 at 18:59
  • @MarkSetchell Awesome suggestion - I'll definitely give it a try! (And imagine I'm a PHP guy...) Thanks a lot! :) – Dr.Kameleon Oct 20 '16 at 03:28

0 Answers0