It seems like the 'Change file format' option doesn't change the file extension.

CommentFileSizeAuthor
#5 ScreenHunter_26 Nov. 10.jpg97.99 KBfietserwin

Comments

dman’s picture

Status: Active » Closed (duplicate)

This is true.
#628146: File extensions don't match the actual MIME type - Some browsers do not display converted images
Do you have a suggestion for how to do it that won't break all the other modules that use imagecache and expect the file to be stored under the old extension? It needs a clever fix.
Suggestions in the linked thread.

kumkum29’s picture

Hello,

I reopened this discussion a year later.
Have you found a solution or a patch to fix this problem?

I use imagecache action + imagemagick + filter "Change Convert to file format". This filter works very well and compress my psd or tif files to new files of jpg type. The problem is that the new extensions of files aren't ".jpg" but .psd or .tif...
Is there a solution?

Thank you for your help.

Imagemagick 7.x.1.0 alpha2+5-dev / Imagecache Actions 7.x.1-0

fietserwin’s picture

And what exactly is the problem, aside a minor aesthetic one? Image styles from Drupal core simply does not cater for the situation where one might change the extension (and/or filename), so it will be very hard for contrib to do anything about it. I have studied the involved core code a few times, but could not find any way to work around it. But if anyone else has an idea, please post it here and I will try to sort out if it can be realized.

(Note : because you didn't change the status this issue will fall off of our list sooner or later and we won't look at it anymore...)

kumkum29’s picture

The images generated by imagecache don't have jpg extension. Images aren't displayed by browsers. Here is the problem.

I'm not a real programmer and I could not help you too much about it ... :(

fietserwin’s picture

StatusFileSize
new97.99 KB

Images are displayed by browsers, i.e. at least in the browsers I tested it, like firefox (16) (and IE9 and Chrome):
ScreenHunter_26 Nov. 10.jpg

kumkum29’s picture

Hello,

thumbnails generated by imagecache / imagecache actions / imagemagick have the following extensions: psd, tif, eps ... Then, thumbnails are not displayed in different browsers.
Would it be possible to create a custom imagecache action that rename image extension via php rename function? This action action is the last action applied by imagecache on the image.

fietserwin’s picture

The problem is not so much in the execution of the image style effect. I guess it would not be too difficult to actually change the extension of the file that gets saved, though as issue #1310452: Allow to override the image toolkit's global JPEG/PNG quality value makes clear, it probably needs a patch for core.

The real problem however, is in the formatters that produce the link to the derived image so that the images can be shown in textfields, blocks or other places. The formatters don't have the information to be able to change the extension. Even if they would have all the effect info, it might be impossible in extreme cases (change format effect after an aspect switcher effect after an autorotate effect).

There are other problems as well. What if we have 2 images a.png and a.jpg. Both would be renamed to a.jpg...

Regarding the browser problem: If I use a tif image as original, it does get displayed as a jpg (tested it in Chrome only) (after the file format conversion and only with imagemagick, GD can't handle tif).

dman’s picture

Yeah, I've never found any *actual* problems with browsers not rendering things even if they are renamed.
But still, saving files with false extensions does bug me as being the wrong thing to do. If you download the files and then try to edit them - yes, some editing programs do complain about corrupt images.

As fietserwin says, the problem isn't about saving the files with an appropriate name (though it is a problem, it could be done with some work) - the problem is getting the renderers, and all the other add-ons that assume they know how to calculate the filenames later to understand that the extension has changed. They would have to know about the way that the action runs, and that's not currently possible.

However - to approach the problem from a different angle, perhaps something could be done on the server - a rewrite rule that could do content-negotiation for missing files. If you ask for derivative/image.tif and it doesn't exist, and we have derivative/image.jpg there instead, serve that?

j0rd’s picture

I'm having problems with this and pinterest.

I have a .png stored in my open graph header og:image="/imagecahce/changeformat/image.png" but it's actually a JPEG.

I think because of the file extension, pinterest assumes it's a PNG and doesn't display it properly.

While it seems to work in most browsers, I believe 3rd party APIs due to poor implementations could have problems with this. I know if I was writing a fetching API, i'd probably use the file extension to determine file type.

Anyways, if anything needs to be hacked (or or otherwise) I'm all for it. I need a solution. I'm using the Drupal 6 variant.

fietserwin’s picture

I believe 3rd party APIs due to poor implementations could have problems with this. I know if I was writing a fetching API, i'd probably use the file extension to determine file type.

That would indeed be a poor implementation. You should use the Content-type header and extension only as fall-back.

But as said, suggestions how to tackle this problem are welcome, because as #8 says, it looks wrong.

dman’s picture

I know it's wrong, and to serve a jpeg and call it a png, or vice versa does give me a headache.
If I found it in any other App or API I would be cursing them.

But until now, I don't have any way to influence the upstream image rendering src filepath generation to tell it that I've changed the jpeg to a png when it wasn't looking.
Please figure out the trigger, hook or API that could be prodded to make this work better.

fietserwin’s picture

OK, what code gets executed and, more important, what hooks are called in between:

function theme_image_style($variables) {
  ...
  $variables['path'] = image_style_url($variables['style_name'], $variables['path']);
  ...
}

function image_style_url($style_name, $path) {
  $uri = image_style_path($style_name, $path);
  ...
  return file_create_url($uri);
}

// function image_style_path does not give us anything to hook into.

function file_create_url($uri) {
  // Allow the URI to be altered, e.g. to serve a file from a CDN or static
  // file server.
  drupal_alter('file_url', $uri);
  ...
}

So, AFAIKS and assuming that we don't hack core, we either do some theme preprocessing on theme 'image_style' or we implement hook_file_url_alter. Given the uproar around the Drupal 7.20 and 7.21 releases, I expect that, if we do something like this, it will break some sites. But I do not consider that our problem, as those sites, or actually some modules used by these sites, are not following the Drupal guidelines.

A theme preprocess does not have to be that costly. It gets only called when an image derivative gets created (one-time operation) and the image style data that we need, will need to be loaded (and probably cached) anyway to be able to create the derivative itself.

On the other hand, the file_url alter hook might get called a lot, so if we choose that one. we should be able to return very quickly if we are not into altering the url passed in.

dman’s picture

Good sleuthing.
So hook_file_url_alter() exists ...
but we probably don't have a lot of context info by the time it gets there. We'd have to do a string search to see if it is one of 'our' image derivatives, but yes, once that is done we do have the power to fix this. Awesome! It's no longer impossible.

Not sure where to put this, and it really should be an edge-case admin option to even turn on. But I love the idea that it CAN be fixed!

fietserwin’s picture

Correct, but we do have that context info when the theme gets called, so it would be preferable to implement hook_preprocess_THEME() for theme image_style (http://api.drupal.org/api/drupal/modules%21system%21theme.api.php/functi...).

But note that the above is about creating links to it. It won''t allow us to alter the name under which the derivative gets created/saved. This is handled/executed via the menu/router system:

function image_menu() {
  ...
  $directory_path = file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath();
  $items[$directory_path . '/styles/%image_style'] = array(
    'title' => 'Generate image style',
    'page callback' => 'image_style_deliver',
    'page arguments' => array(count(explode('/', $directory_path)) + 1),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  ...
}

function image_style_deliver($style, $scheme) {
  $args = func_get_args();
  array_shift($args);
  array_shift($args);
  $target = implode('/', $args);
  ...
  $image_uri = $scheme . '://' . $target;
  $derivative_uri = image_style_path($style['name'], $image_uri);
  ...
  $success = file_exists($derivative_uri) || image_style_create_derivative($style, $image_uri, $derivative_uri);
  ...
}

So if we would have implemented something based on #12 to change the link (via a theme preprocess or file_url_alter), image_style_deliver() will fail as there is no way we can hook into this code to change $image_uri.
Though the derivative uri (the q parameter of the request) is recomputed from the image_uri, after image_uri has been computed from the derivative uri (the requested URL), there is no way we can hook into this process. This would leave us no other option than to hijack the path $directory_path . '/styles/%image_style' with hook_menu_alter() and bypass image_style_deliver() altogether.

The good thing is that image_style_create_derivative() seems to allow the use of different unrelated file names or extensions, as both source and target are passed in separately.

Talkless’s picture

Issue summary: View changes

So.. any news? Last post was a year ago...

I wanted to force JPEG format as PNG are just too heavy and unnecessary (no transparency expected), and noticed that it's still a .png extension in generated image paths. If you want to save-as, Firefox 32 suggests "file.png.jpg" filename...

mibfire’s picture

i cant believe this issue still exists!

parkout’s picture

2019 year and this still exist

le72’s picture

It's 2020, the issue still present.

fietserwin’s picture

Except that there is no issue.

steffenr’s picture

The image cache action Chnage file format works fine for modern browsers.
But in case of using IE11 - yes still active for some customers - the image delivery is broken, cause the .htaccess direction Header always set X-Content-Type-Options nosniff is set for security reasons.

fietserwin’s picture

In case of IE11 the world wide web is indeed broken in many places and in many ways, and not only due to this feature. If, for whatever reason, you want to cater for these customers, change format before uploading.