Using the C API for ImageMagick (on iPhone?) to convert to monochrome?

前端 未结 1 871
攒了一身酷
攒了一身酷 2020-12-05 12:32

I am using the code referenced in this post, but would like to switch to an ImageMagick C-API based solution, as I want to standardize on a single image manipulation library

相关标签:
1条回答
  • 2020-12-05 12:46

    You can achieve monochrome conversion, as described here, with MagickQuantizeImage function. I'm not quite familiar with dithering images, but an example may look like the following.

    #include <wand/MagickWand.h>
    
    int main(int argc, char **argv) 
    {
      const size_t number_colors = 2;
      const size_t treedepth     = 1;
      MagickWandGenesis();
      MagickWand *wand = NULL;
      wand = NewMagickWand();
      MagickReadImage(wand,"source.png");
      MagickQuantizeImage(
                         wand,            // MagickWand
                         number_colors,   // Target number colors
                         GRAYColorspace,  // Colorspace
                         treedepth,       // Optimal depth
                         MagickTrue,      // Dither
                         MagickFalse      // Quantization error
                     );
      MagickWriteImage(wand,"out.png");
      if(wand)wand = DestroyMagickWand(wand);
      MagickWandTerminus();
      return 0;
    }
    

    This can give you a rather speckled image at times.

    Monochrome with dither

    Adjusting depth, color-number, and/or disabling dithering may give you results closer to what you would expect from the examples provided.

    MagickQuantizeImage(
                       wand,            // MagickWand
                       number_colors,   // Target number colors
                       GRAYColorspace,  // Colorspace
                       treedepth,       // Optimal depth
                       MagickFalse,     // No-dither
                       MagickFalse      // Quantization error
                   );
    

    Like such... Monochrome without dither

    For iOS

    Not much effort is needed to port the example code to iOS. NextStep/Objective-c methods are compatible with MagickWand library. The following example uses a temporary file to store the monochrome image, but I'm sure there is a better way to pass Magick image-data directly to UImage object.

    // MyViewController.h
    #import <UIKit/UIKit.h>
    #import <wand/MagickWand.h>
    
    @interface MyViewController : UIViewController
    
    @property (retain, nonatomic) IBOutlet UIImageView *imageView;
    @property (retain, nonatomic) MagickWand *wand;
    
    @end
    
    // MyViewController.m
    #import "MyViewController.h"
    
    @implementation MyViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        MagickWandGenesis();
        self.wand = NewMagickWand();
        [self drawMonochromeImage:@"logo:"];
    }
    
    -(void)drawMonochromeImage:(NSString *)filePath
    {
        // Create temporary file
        NSString *tempFilePath = [NSTemporaryDirectory() 
                                     stringByAppendingPathComponent:@"logo.jpg"];
    
        // Read given image with C-string
        MagickReadImage(self.wand,
            [filePath cStringUsingEncoding:NSASCIIStringEncoding]
        );
    
        // Monochrome image
        MagickQuantizeImage(self.wand,2,GRAYColorspace,1,MagickFalse,MagickFalse);
    
        // Write to temporary file
        MagickWriteImage(self.wand,
            [tempFilePath cStringUsingEncoding:NSASCIIStringEncoding]
        );
    
        // Load UIImage from temporary file
        UIImage *imgObj = [UIImage imageWithContentsOfFile:tempFilePath];
    
        // Display on device
        [self.imageView setImage:imgObj];
        [self.imageView setContentMode:UIViewContentModeScaleAspectFit];
    }
    -(void)viewDidUnload
    {
        // Clean-up
        if (self.wand)
            self.wand = DestroyMagickWand(self.wand);
        MagickWandTerminus();
    }
    
    @end
    

    iOS Simulator

    0 讨论(0)
提交回复
热议问题