Archive for category MovingImages

Drawing rotated text with CoreText is broken

Here is a video where the text is being rotated at different angles. You can see from the flickering that at certain angles the text just doesn’t get drawn.

 

And here is a video where I’ve created a bitmap of the text drawn unrotated and then I draw the bitmap rotated at different angles. Which works:

 

I am drawing the core text within a path rather than from a point and I think that is the issue. I have seen in other situations when drawing multi-line wrapping text in a a path that is a column then if the drawing happens while the context is rotated then at certain angles the line wrapping for the first line of text behaves oddly.

I get exactly the same behaviour on iOS as I do on OS X.

This is definitely an issue of drawing the text within a path, drawing the text from a point works as expected.

Tags:

Accessing CoreImage transition filters from the command line

As part of MovingImages I wrote a number of command line tools that can take advantage of MovingImages. The command line tools are written in ruby and most of them come with the MovingImages ruby gem so after installing MovingImages these command line tools are installed. If you haven’t already you’ll need to download and install MovingImages.

This blog post is about the ‘dotransition’ command line tool. This tool provides access to CoreImage’s transition filters. A CoreImage transition filter takes a source and target images and provides a way of transitioning from the source image to the target image by generating a sequence of images that represents the transition between the two images.

The command line tools all take the “–help” option which describes how to call the command line tool with the various options, and they all also take the “–verbose” option which can be useful when you get an error calling the script.

In all the examples I am going to assume that the source image is an jpeg image file in your Pictures folder called “sourceimage.jpg” and that the destination image is an image file in your Pictures folder called “targetimage.jpg”. The generated images are saved in a sub folder of a folder called transition on your desktop. The first example uses the long form of the command line options as they are more descriptive but it does result in longer commands. The other examples use a mixture of long and short form demonstrating that they can be mixed. The filter specific options are only available in the long form. The ‘dotransition’ command line tool assumes that source and target images are the same size.

The bar swipe transition uses the CoreImage filter CIBarsSwipeTransition

dotransition --transitionfilter CIBarsSwipeTransition --basename image --outputdir ~/Desktop/transition/barswipe --baroffset 60 --angle 2.0 --width 20 --sourceimage ~/Pictures/sourceimage.jpg --targetimage ~/Pictures/targetimage.jpg --exportfiletype public.jpeg --count 20

I’ll cover the command line options that are common to all the transition filters first. The “–transitionfilter” option specifies the transition filter to use. To get a list of the available transition filters call the do transition command line tool like so:

dotransition -l

The ‘dotransition’ command generates a sequence of image files. These images are created in the directory specified after the –outputdir option. If the path to the directory contains a space or other non standard character then the path will need to be quoted or escaped. To generate the file names ‘dotransition’ takes a –basename option which specifies the beginning of the filename, which is then followed by the image sequence number and then the file extension for the file type of the generated image. The –sourceimage option specifies the image file that the transition starts with, and the the –targetimage option specifies the transition ends with. Like the –outputdir option if the path contains spaces or other non standard path character then the path will need to be quoted or escaped. The –exportfiletype is optional and defaults to public.tiff if not specified. The –count option specifies the number of images in the image sequence to be generated.

The bar swipe transition takes a number of filter specific properties. These are –baroffset, –angle, –width. To determine the filter properties that belong to a specific filter you can request that from the dotransition command line tool.

dotransition --filterproperties CIBarsSwipeTransition

Which outputs the information about each property. You can use the filter key value to match with the equivalent command line option.

The ripple transition filter creates a ripple effect when transitioning from one image to another. The following example assumes that the input images have a width of 2272 and a height of 1704 pixels. The ripple effect is to center itself on the image.

dotransition --transitionfilter CIRippleTransition -b image -o ~/Desktop/transition/ripple --center 1136,852 --scale=40.0 --width 50 --extent 0,0,2272,1704 -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 20

The swipe transition replaces the source image with the destination by swiping away the source image.

dotransition --transitionfilter CISwipeTransition -b image -o ~/Desktop/transition/swipe --angle 2.0 --width 150 --color 0.3,0.2,0.8,1.0 --extent 0,0,2272,1704 --opacity 0.7 -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -t public.jpeg -c 20

The copy machine transition, imitates the action of a photocopier, but replaces the source image with the target as it passes.

dotransition --transitionfilter CICopyMachineTransition -b image -o ~/Desktop/transition/copymachine --angle=-2.0 --width 100 --color 0.8,0.2,0.6,1.0 --extent 0,0,2272,1704 --opacity 0.85 -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 30

The disintegrate with mask transition takes a mask image which it applies to the transition effect. For best results the mask image should be black and white and the same dimensions as the source and destination images.

dotransition --transitionfilter CIDisintegrateWithMaskTransition -b image -o ~/Desktop/transition/disintegratemask --maskimage ~/Pictures/maskimage.jpg --shadowradius 80 --shadowdensity 0.8 --shadowoffset 10,25 -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 20

The flash transition filter generates a flash image over the source image which is then replaced by the target image.

dotransition --transitionfilter CIFlashTransition -b image -o ~/Desktop/transition/flash --extent 0,0,2272,1704 --color 0.0,0.2,0.8,1.0 --striationcontrast 2.0 --fadethreshold 0.8 --striationstrength 1.0 --center 1136,852 -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 40 -t public.jpeg

The dissolve transition is the simplest of the transition filters, where the source image is gradually replaced with the target image. This example shows exporting the images as a png sequence. Exporting as png files is considerably slower than jpeg or tiff.

dotransition --transitionfilter CIDissolveTransition -b image -o ~/Desktop/transition/dissolve --exportfiletype public.png -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 20

The mod transition filter creates oblated oval shapes that move and grow, gradually replace the source image with the target.

dotransition --transitionfilter CIModTransition -b image -o ~/Desktop/transition/mod  -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 20 --angle 3.14159 --radius 340 --compression 300 --center 1136,852

The page curl transition filter, creates a page turning effect to go from the source to the target image.

dotransition --transitionfilter CIPageCurlTransition -b image -o ~/Desktop/transition/pagecurl  -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 20 --angle 3.2 --radius 250 --extent 0,0,2272,1704 --backsideimage ~/Pictures/sourceimage.jpg

The page curl with shadow transition filter is very similar to the above but generates the shadow of the page being turned differently.

dotransition --transitionfilter CIPageCurlWithShadowTransition -b image -o ~/Desktop/transition/pagecurlwithshadow  -s ~/Pictures/sourceimage.jpg -d ~/Pictures/targetimage.jpg -c 20 --angle 3.2 --radius 350 --extent 0,0,2272,1704 --shadowamount 0.7 --shadowsize 250 --backsideimage ~/Pictures/sourceimage.jpg

Information about all the scripts that work with MovingImages.

And that’s it, please enjoy.

Tags: ,

MovingImages Alpha Release 3

MovingImages

Download MovingImages

MovingImages Documentation

MovingImages Ruby Gem Reference Documentation

Examples and documentation for image processing scripts

An introduction to the different components of MovingImages and how they interact

Read the rest of this entry »

Tags: ,

Thinking about my tests

I’ve installed Yosemite and of course the first thing I did was to run my tests

Almost every test failed. Generated images are all different. They look the same to my poor eyesight but pixel values can be quite different with the compare tolerance increased to 26* from 0 needed for an image to be identified as the same. I had previously only needed to do this when comparing images created from windows on different monitors. I think perhaps I need to have a think about exactly what it is I’m testing. These tests have saved me a lot of time and given me confidence that I’ve not been breaking stuff but for so many to break with an os upgrade doesn’t help.

For now the failure of the tests beyond the image generation described above, has informed me about the following changes to ImageIO and CoreImage filters.

Information returned about functionality provided by ImageIO and CoreImage

ImageIO can now import three new formats: “public.pbm”, “public.pvr”, “com.apple.rjpeg”
ImageIO has lost one import format: “public.xbitmap-image”

I’ve no idea what these formats are and I’ve been unsuccessful at finding information about them.

ImageIO has added export formats: “public.pbm”, “public.pvr”, “com.apple.rjpeg”

Apple has added these new CoreImage filters:

CIAccordionFoldTransition CIAztecCodeGenerator CICode128BarcodeGenerator CIDivideBlendMode CILinearBurnBlendMode CILinearDodgeBlendMode CILinearToSRGBToneCurve CIMaskedVariableBlur CIPerspectiveCorrection CIPinLightBlendMode CISRGBToneCurveToLinear CISubtractBlendMode

There are minor configuration or filter property changes to the filters listed below with a brief description of the change:

  • CIBarsSwipeTransition inputAngle given updated values for default and max. Identity attributes removed for inputWidth and inputBarOffset.
  • CIVignetteEffect inputIntensity slider min changed from 0 to -1.
  • CIQRCodeGenerator has spaces added to description of one property, and a description added for another.
  • CILanczosScaleTransform has a fix for the filter display name.
  • CIHighlightShadowAdjust inputRadius has minimum slider value changed from 1 to 0.
  • CICMYKHalftone inputWidth attribute minimum changed from 2 to -2. inputShapness attribute type is CIAttributeTypeDistance not CIAttributeTypeScalar
  • CICircleSplashDistortion inputRadius has a new identity attribute with value 0.1
  • CIBumpDistortionLinear inputScale, inputRadius and inputCenter given slightly more rational default values.
  • CIBumpDistortion inputScale, and inputRadius are given slightly more rational defaults.
  • CIBarsSwipeTransition inputAngle given updated values for default and max. Identity attributes removed for inputWidth and inputBarOffset.

*This is comparing images created from a 8 bit per color component bitmap context. So out of a range of 256 possible values images generated on Mavericks compared to ones generated on Yosemite are different by up to 26 of those 256 values. That’s huge.

A year in review with MovingImages

It has been a little over a year since I started working on the MovingImages project. I wanted to build something that was similar to “iMagine Photo” which I created over 10 years ago, but with more functionality and provide the users writing scripts with a greater choice of scripting languages to use to drive MovingImages.

Read the rest of this entry »

MovingImages alpha release 2

I’m pleased to announce this second alpha release of MovingImages.

An introduction to what MovingImages is.

Version 0.2 alpha adds:

• Added the ability to setup and render core image filter chains.
• Added logging functionality useful for debugging drawing and filter rendering commands
• Added a chroma key filter to the list of available core image filters.
• Added an option to return a list of core graphics blend modes
• Added option for naming base objects when they are created for later identification.
• Added system tests for MovingImages
• Added a get pixel data option
• Added affine transform as an option for the various draw element commands.
• Added affine transform as an optional property for drawing text
• Added text alignment as a drawbasicstring attribute
• Added a coreimageblend script to be distributed with MovingImages
• Added a dotransition script to be distributed with MovingImages
• Added a simplesinglecifilter script to be distributed with MovingImages

Download MovingImages

Instructions for Installing MovingImages

An introduction to what MovingImages is

The Using MovingImages documentation

Please make suggestions, especially about image processing scripts you’d like to see written, report any bugs that you find, including documentation bugs. I am super keen to help people get started writing their own scripts for MovingImages so if you would like to do so don’t hesitate to get in touch. My e-mail is support[at]yvs.eu.com.

I intend to keep MovingImages as a free product.

MovingImages comes with a collection of image manipulation scripts and a collection of CoreImage filter processing scripts.

A first draft of an ebook for the Using MovingImages documentation

Enjoy!

Tags: ,

Core Image Filter Rendering. Performance & color profiles

The Apple documentation for rendering a core image filter chain notes that allowing the filter chain to render in the Generic Linear color space is faster. If you need better performance and are willing to trade that off against better color matching then allowing the filter chain to render in the generic linear color space should be faster.

I thought I better look at what the impact of this was both for performance and color matching. I also wanted to see what the difference was if the core graphics context that the filter chain rendered to was created with a sRGB color profile or a Generic Linear RGB profile when the context bitmap was saved as an image to an image file.

All the tests were done on my laptop with the following configuration:

OS: Mavericks 10.9.2
System information: MacBookPro non retina, model: MacBookPro9,1
Chipset Model:	NVIDIA GeForce GT 650M 500MByte.
Chipset Model:	Intel HD Graphics 4000
A 512GByte SSD, 16GByte RAM.

I installed gfxCard Status tool sometime ago which allows me to manually switch which cards to use, and also to inform me when the system automatically changes which card is in use. I use to get changes reported regularly but after one of the Mavericks updates this happened much less. After that update the only consistent way for the discrete card to be switched on automatically by the system was having an external monitor plugged in. I think the OS is trying much harder to keep the discrete graphics card turned off. I have NSSupportsAutomaticGraphics switching key in my info.plist set to YES. I have tried setting the value to NO, and if I run the tests then as long as software render is not specified I’m informed that the system has turned the discrete graphics card on but the CoreImage filter render performance is still poor. The consequence is I’m not really sure that the discrete graphics card is being used for these tests. Perhaps I’d get different results as to whether GPU rendering or software rendering was faster if I had a more complex filter chain so what I might be seeing here is the time needed to push the data to the graphics card, and then pull it back dominating the timing results.

First up, when comparing images where the only difference in image generation has been whether they are rendered to a CGContext with a sRGB profile or a Generic Linear RGB profile then when I view the images in Preview they look identical. The reported profiles are different, the image generated from a context with Generic Linear RGB has a reported profile of Generic HDR profile while the image from a context with a SRGB profile has a reported profile of sRGB IEC61966-2.1.

When the filter chain has the straighten filter and it rotates the image 180 degrees the colors of the output image are exactly the same as the input image when viewed in Preview, no matter the options for generating the output image.

When the filter chain has the box blur filter applied with a radius of 10 pixels the image rendered in the linear generic rgb profile is lighter than the one rendered using the sRGB profile when viewing the output images in preview. The image rendered using the sRGB looks to match better the original colors of the image. The generic linear rgb profile appears to lighten the image. The color change is not large and would be probably be acceptable for real time rendering purposes.

Setting kCIContextUseSoftwareRenderer to YES or NO when creating the CIContext makes no difference in terms of the color changes.

However I get the opposite of what I’d expect with speed.

Asking the filter chain with filter CIBoxBlur with radius of 10 to render 200 times to a Core Graphics context with a sRGB color profile:

Software render using sRGB profile: 4.1 seconds
Software render using Linear Generic RGB profile: 5.3 seconds
GPU render using sRGB profile: 7.0 seconds
GPU render using Linear Generic RGB profile: 7.5 seconds

If I create a Core Graphics context with a Generic Linear RGB color profile then:

Software render using sRGB profile: 4.0 seconds
Software render using Linear Generic RGB profile: 5.3 seconds
GPU render using sRGB profile: 7.3 seconds
GPU render using Linear Generic RGB profile: 7.7 seconds
  1. These results are completely 180º turned around from the results that I’d expect. If I was to accept them as unquestioned truth then I’d have to decide to always just work using the sRGB profile and to do all rendering via software and not worry about using the GPU unless I needed to offload work from the CPU.

A later observation (Friday 2nd Mary 2014), when drawing text into a bitmap context and running off battery power, I’m informed that the system has switched temporarily to using the discrete graphics card and then informed soon after it has switched back.

Tags: , ,

MovingImages CoreImage Transition Filter Example

I’ve written a number of ruby scripts that use MovingImages. One of the recent ones takes advantage of the CoreImage filter functionality that I’ve recently hooked into Moving Images. You’ll get to see this in the second alpha release which I’m pleased to say will be released soon.

The script is called exactly as shown below:

./dotransition --count 30 --sourceimage "/Users/ktam/Pictures/20140422 Pictures/DSC01625Small2.JPG" --destinationimage "/Users/ktam/Pictures/20140422 Pictures/DSC01625Small2.JPG" --basename PageCurl --outputdir "~/Desktop/deleteme/" --backsideimage "/Users/ktam/Pictures/20140422 Pictures/DSC01625SmallCropped.jpg" --angle=-3.07 --transitionfilter CIPageCurlTransition --extent 0,0,463,694 --verbose

I then used a script that you can download that works with the first alpha release of MovingImages and was called exactly as shown below:

./createanimation --delaytime 0.1 --outputfile ~/Desktop/PageTurningAnimation.gif --verbose ~/Desktop/deleteme/PageCurl*.tiff

The result of running both those scripts

Gif animation where the same page is turned over forever

The MovingImages documentation shows the output images at each step of the filter chain. Scroll down past the generated json code to see the images.

The create animation script can be viewed here.

The do transition script can be viewed here.

And an earlier demonstration using the embossmask script

Moving Images

Alpha Release v0.1a of MovingImages

I’m pleased to announce this first alpha release of MovingImages. Writing the using MovingImages documentation has taken longer than could have been imagined. The reference documentation is not yet written.

Download MovingImages.

Instructions for Installing MovingImages

An introduction to what MovingImages is

The Using MovingImages documentation

An alpha release of software is a pre-release version of the software, that is not feature complete but that has useful functionality that can test the design of the software. There are significant important features of MovingImages that are missing like image filters, and movie frame processing. These will come in future releases of MovingImages.

Please make suggestions, especially about image processing scripts you’d like to see written, report any bugs that you find, including documentation bugs. I am super keen to help people get started writing their own scripts for MovingImages so if you would like to do so don’t hesitate to get in touch. My e-mail is support[at]yvs.eu.com.

I intend to keep MovingImages as a free product.

MovingImages comes with a collection of image processing scripts. Description of the MovingImages scripts.

Enjoy!

Tags: ,