Here's how I migrated my D6 imagecache presets to D7 image styles:

1. I exported all of my imagecache presets on the D6 site via features into a features module.

2. I changed the features module's .info file to be a 7.x module.

3. I added the following to its .module file:


function MY_FEATURE_NAME_image_styles_alter(&$styles) {
  foreach (module_implements('imagecache_default_presets') as $module) {
    $module_styles = module_invoke($module, 'imagecache_default_presets');
    foreach ($module_styles as $style_name => $style) {
      $style['name'] = $style_name;
      $style['module'] = $module;
      $style['storage'] = IMAGE_STORAGE_DEFAULT;
      foreach ($style['actions'] as $key => $effect) {
        $effect['action'] = str_replace('cache', '', $effect['action']);
        $definition = image_effect_definition_load($effect['action']);
        $effect = array_merge($definition, $effect);
        $style['effects'][$key] = $effect;
      }
      $styles[$style_name] = $style;
    }
  }
}

4. I enabled the module on the D7 site. Voila my image styles are now all loaded in D7.

5. I recreated the feature module on the D7 site and added all the new image styles to it (as opposed to what were imagecache presets).

6. I removed the function I added in 3.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dman’s picture

Sweet contribution!
Thanks for posting that sort of stuf :-)

justindodge’s picture

Status: Needs work » Reviewed & tested by the community

Brilliant, worked like a charm. Thank you!!!

John Pitcairn’s picture

Jody, that's superb. Works like a dream, many thanks.

wladimirww’s picture

My solution is:
Create file in "DRUPAL_ROOT" and paste the code.
Open it.


define('DRUPAL_ROOT', getcwd());

require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);


/////////////////////////////////////////////////
function imagecache_preset_actions($preset, $reset = FALSE) {
  $actions_cache = array();


    $result = db_query('SELECT * FROM {imagecache_action} where presetid = '.$preset['presetid'].' order by weight' );
    foreach ($result as $row ) {
	$row=(array)$row;
      $row['data'] = unserialize($row['data']);
      $actions_cache[$preset['presetid']][] = $row;
    }

  return isset($actions_cache[$preset['presetid']]) ? $actions_cache[$preset['presetid']] : array();
}
/////////////////////////////////////////////////

/////////////////////////////////////////////////
function imagecache_presets() {
  $presets = array();

	$normal_presets = array();

	$result = db_query('SELECT * FROM {imagecache_preset} ORDER BY presetname');
	
	foreach ($result as $preset) {
	  $preset=(array)$preset;
	  $presets[$preset['presetid']] = $preset;
	  $presets[$preset['presetid']]['actions'] = imagecache_preset_actions($preset);
	  $presets[$preset['presetid']]['storage'] = 0;

	  // Collect normal preset names so we can skip defaults and mark overrides accordingly
	  $normal_presets[$preset['presetname']] = $preset['presetid'];
	}

  return $presets;
}
/////////////////////////////////////////////////

/////////////////////////////////////////////////
$styles_cnt=0;
$effects_new_cnt=0;
$effects_ext_cnt=0;

$presets=imagecache_presets();
foreach($presets as $preset)
	{
	$styles_cnt++;// inc styles
	
	$style=image_style_load($preset['presetname']);
	
	$style['name']=$preset['presetname'];
	$style=image_style_save($style);
	if(!isset($style['effects']))
		{
		$style['effects']=array();
		}
	foreach($preset['actions'] as $action)
		{
		$action['action']=str_replace('imagecache','image',$action['action']);
		$action['module']=str_replace('imagecache','image',$action['module']);
		
		$effect_ieid=FALSE;// effect not exists
		foreach($style['effects'] as $effect)
			{
			if($effect['name'] == $action['action'] && 
				$effect['module'] == $action['module'] && 
				$effect['weight'] == $action['weight'] && 
				$effect['data'] == $action['data'] )
				{
				$effect_ieid=$effect['ieid'];// effect exists
				}
			}
		$effect=array();	
		if($effect_ieid)
			{
			$effects_ext_cnt++;// inc exists 
			$effect=image_effect_load($effect_ieid,$style['name']);
			}
		else
			{
			$effects_new_cnt++;// inc new
			$effect=image_effect_definition_load($action['action']);
			}
		
		$effect['isid'] = $style['isid'];	
			
		$effect['name'] = $action['action'];
		$effect['module'] == $action['module'];
		$effect['weight'] = $action['weight'];
		$effect['data'] = $action['data'];
		$effect = image_effect_save($effect);
		$style['effects'][$effect['ieid']] = $effect;
		}
	$style=image_style_save($style);
	}

print "Styles: $styles_cnt,	Effects new: $effects_new_cnt, Effects exists: $effects_ext_cnt \n";

philsward’s picture

I will note that comment #4 must be run AFTER D7 is in place. Make sure to enable "File" and "Image" before running the code. It can be run before or after the image field migration process.

I simply created a "migrate.php" file, copied the code and it successfully imported the info. It will NOT work on the D6 install. I haven't figured out a way to preserve the views images yet though...

pipicom’s picture

I confirm that #4 and #5 helped me do the job.. Thanks wladimirww :)

fizk’s picture

Status: Reviewed & tested by the community » Closed (fixed)

Great work!

esha’s picture

works like a charm, thanks a lot!

danyg’s picture

Thank You very much, #4 worked for me.

shark’s picture

I ran #4 on the command line and saw this error:

PHP Stack trace:
PHP 1. {main}() /var/www/mysite/d7/drupal/imagecache-to-styles.php:0
PHP 2. image_style_save() /var/www/mysite/d7/drupal/imagecache-to-styles.php:59
PHP 3. drupal_write_record() /var/www/mysite/d7/drupal/modules/image/image.module:669
PHP 4. drupal_get_schema() /var/www/mysite/d7/drupal/includes/common.inc:7015
PHP 5. SchemaCache->__construct() /var/www/mysite/d7/drupal/includes/bootstrap.inc:2874
PHP 6. _drupal_error_handler() /var/www/mysite/d7/drupal/includes/bootstrap.inc:0
PHP 7. _drupal_error_handler_real() /var/www/mysite/d7/drupal/includes/bootstrap.inc:2238
PHP 8. _drupal_log_error() /var/www/mysite/d7/drupal/includes/errors.inc:75
PHP 9. watchdog() /var/www/mysite/d7/drupal/includes/errors.inc:202
PHP 10. ip_address() /var/www/mysite/d7/drupal/includes/bootstrap.inc:1707
PHP Notice: Undefined index: REMOTE_ADDR in /var/www/ecowiki/d7/drupal/includes/bootstrap.inc on line 2821

However, commenting out the first few lines

// define('DRUPAL_ROOT', getcwd());
// require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
// drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

and running it in drush worked:

drush @mysite scr imagecache-migration.php

jhodgdon’s picture

FileSize
1.27 KB

Here's another way to run the code in #4:
a) Download the attached module.
b) Unzip into your sites/all/modules directory.
c) Enable the module (it's called Imagecache Migrate).
d) Edit the module.install file. Change the number on the update function from migrate_styles_update_7000 to migrate_styles_update_7001.
e) Run your update.php script.
f) Disable the module.

Basically I just took the code in #4 and put it into an update function. The problem is that when you first enable a module, Drupal figures out that you are already updated to the number of the latest update function that is there. So that is why step d is necessary, to convince Drupal this is a new update function that you need to run. I guess the better route would have been to name the module "imagecache" so that Drupal would know it hadn't run any Drupal 7 updates for imagecache yet. Oh well. Hope this helps someone.

chipway’s picture

FileSize
1.3 KB

Just repackaged #11 jhodgdon modules under a folder to make :
wget of attached file
tar -zxvf migrate_styles.tgz
cd migrate_styles

work easily.

heldercor’s picture

Why not place the update code in hook_enable? That way you don't have to go in there and manually change the update number.

kevinsiji’s picture

Solution in #4 worked like a charm.

kenorb’s picture

kenorb’s picture

Posted here for better tracking:
https://drupal.org/sandbox/kenorb/migrate_styles

chunty’s picture

Solution #4 nearly works for me but it doesn't take into account that in D6 if you had a scale action when you only wanted to scale one dimension you would do something like

width:250 height: 100%

However in D7 you simply leave height blank, this direct import causes the image style to do the wrong thing, it effectively treats 100% as 100px, and its only when you try to edit it that the problem becomes apparent.

In addition unless I'm completely missing something (and I've posted here: https://drupal.org/node/2210363) cropping now requires both dimensions so you can't just crop width or height (100% used to work).

I've improved this file a little to support this:

<?php
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
/////////////////////////////////////////////////
function imagecache_preset_actions($preset, $reset = FALSE) {
  $actions_cache = array();
    $result = db_query('SELECT * FROM {imagecache_action} where presetid = '.$preset['presetid'].' order by weight' );
    foreach ($result as $row ) {
    $row=(array)$row;
      $row['data'] = unserialize($row['data']);
      $actions_cache[$preset['presetid']][] = $row;
    }
  return isset($actions_cache[$preset['presetid']]) ? $actions_cache[$preset['presetid']] : array();
}
/////////////////////////////////////////////////
/////////////////////////////////////////////////
function imagecache_presets() {
  $presets = array();
    $normal_presets = array();
    $result = db_query('SELECT * FROM {imagecache_preset} ORDER BY presetname');
    foreach ($result as $preset) {
      $preset=(array)$preset;
      $presets[$preset['presetid']] = $preset;
      $presets[$preset['presetid']]['actions'] = imagecache_preset_actions($preset);
      $presets[$preset['presetid']]['storage'] = 0;
      // Collect normal preset names so we can skip defaults and mark overrides accordingly
      $normal_presets[$preset['presetname']] = $preset['presetid'];
    }
  return $presets;
}
/////////////////////////////////////////////////
/////////////////////////////////////////////////
$styles_cnt=0;
$effects_new_cnt=0;
$effects_ext_cnt=0;
$presets=imagecache_presets();
$failedpresets = array();
foreach($presets as $preset)
    {
    $styles_cnt++;// inc styles
    $style=image_style_load($preset['presetname']);
    $style['name']=$preset['presetname'];
    $style=image_style_save($style);
    if(!isset($style['effects']))
        {
        $style['effects']=array();
        }
    foreach($preset['actions'] as $action)
        {

        $action['action']=str_replace('imagecache','image',$action['action']);
        $action['module']=str_replace('imagecache','image',$action['module']);
        $effect_ieid=FALSE;// effect not exists
        foreach($style['effects'] as $effect)
            {
            if($effect['name'] == $action['action'] &&
                $effect['module'] == $action['module'] &&
                $effect['weight'] == $action['weight'] &&
                $effect['data'] == $action['data'] )
                {
                $effect_ieid=$effect['ieid'];// effect exists
                }
            }
        $effect=array();
        if($effect_ieid)
            {
            $effects_ext_cnt++;// inc exists
            $effect=image_effect_load($effect_ieid,$style['name']);
            }
        else
            {
            $effects_new_cnt++;// inc new
            $effect=image_effect_definition_load($action['action']);
            }
        $effect['isid'] = $style['isid'];
        $effect['name'] = $action['action'];
        $effect['module'] == $action['module'];
        $effect['weight'] = $action['weight'];
        if ($effect['name'] == 'image_scale') {
          if ($action['data']['height']=='100%') {
            $action['data']['height']='';
          }
          if ($action['data']['width']=='100%') {
            $action['data']['width']='';
          }
        }
        if ($effect['name'] == 'image_crop') {
          if ($action['data']['width']=='100%' || $action['data']['height']=='100%') {
            $failedpresets[] = $style['name'];
          }
        }

        $effect['data'] = $action['data'];
        $effect = image_effect_save($effect);
        $style['effects'][$effect['ieid']] = $effect;
        }
    $style=image_style_save($style);
    }
print "Styles: $styles_cnt,    Effects new: $effects_new_cnt, Effects exists: $effects_ext_cnt \n";
if (count($failedpresets)) {
  print "<br><br>The following presets may not work correct as cropping now requires that both height and width are specified:<br/> - ".implode('<br/> - ', $failedpresets);
}
?>
yurg’s picture

#17 worked like a charm for D6.16 -> D7.35 migration, thank you!

chunty’s picture

FileSize
1.32 KB

I've improved my code in #17 now so that it caters better for this problem. Now if it spots an image crop action with a dimension of 100% it will check to see if the previous action was an image resize and use the appropriate dimension...its not a perfect method but it sorted all my styles fine.

Extract migrate-d6-image-cache.zip from #20 to your site root and run http://[yourdomain.com]/migrate-d6-image-cache.php from a browser. It will give you a list of image styles that might not do what you were expecting.

Please ignore "image-cache.zip" that has some custom code for the site I was working on and was uploaded in error.

chunty’s picture

FileSize
1.29 KB
bisonbleu’s picture

Many thanks @chunty! Code in #20 worked for me: D6.35 -> D7.43.

How to:

  • place migrate-d6-image-cache.php in your Drupal 7 root directory
  • change queries in lines 8 and 21 to point to your D6 database; e.g. db_query('SELECT * FROM {d6database.imagecache_action} where...
  • go to: your-D7-website.com/migrate-d6-image-cache.php; a plain report will be displayed
  • go to: your-D7-website.com/admin/config/media/image-styles; your new styles should be there
shafiqhossain’s picture

With reference to migrate-d6-image-cache.zip @chunty! Code:

One of the issue is "Scale and Crop" width and height. If width/height was 100%, will it work? Currently in D7, "Scale and Crop" not accept "%" in width or height. It accept only in pixel. How can I migrate that ?

thanks