image icon indicating copy to clipboard operation
image copied to clipboard

Transparency not detected when image url doesn't contain an extension

Open narduin opened this issue 4 years ago • 12 comments

Hello!

I'm using nuxt in full static mode with directus as a content source. Directus has a media library which provides a path to display the files. The path is built as follows: http://[directus-url]/assets/[FILE_ID] ex: http://localhost:8055/assets/db6b1d10-3ab0-4c20-a088-0f0246ae3145

When using nuxt-picture with that url as src, it renders a transparent webp as expected but the fallback generated is a .jpeg with a black background.

I tested with a local path to the file /assets/image.png and a distant path containing the .png extension and all is working fine.

Is it an expected behaviour? Thanks!

nuxt v2.15.7 nuxt-img v0.5.0

narduin avatar Jul 15 '21 10:07 narduin

I had a similar issue where my url doesn't have a mime type extension. eg. http://localhost/image-id when statically generated was getting a file path like /_nuxt/img/image-id.[ext].

I guess there should be a default format set in the provider or we need to pass in the format we want so the image generates using the correct mime type format.

See the nuxt-image format docs: https://image.nuxtjs.org/components/nuxt-img#format

shadow81627 avatar Jul 16 '21 04:07 shadow81627

Passing format="" works on <nuxt-img> and <nuxt-picture> but does it make sense to use <nuxt-picture> like this if we're using the original format? I usually use <nuxt-picture> to get .webp images with a fallback which, here, defaults to a .jpeg with a black background instead of transparency (in case of png files without extensions).

narduin avatar Jul 16 '21 09:07 narduin

There is an issue that is looking at adding a <nuxt-source> component that can be used in the default slot of <nuxt-picture> to control images sources. #309

There is a comment that mentions using legacy format in that issue thread as well https://github.com/nuxt/image/issues/309#issuecomment-876827549

shadow81627 avatar Jul 16 '21 10:07 shadow81627

Yes I've used the workaround from that issue somewhere else but it's not the same problem as my issue I believe.

narduin avatar Jul 16 '21 11:07 narduin

The code for nuxt-picture to define the legacy format uses the url and I guess that is returning null which is being calculated as not transparent. Do you have any suggestions on how the below code should handle the extension being null?

getFileExtension (url: string = '') {
  const extension = url.split(/[?#]/).shift()!.split('/').pop()!.split('.').pop()!
  return extension
}
originalFormat(): string {
  return getFileExtension(this.src)
},
isTransparent(): boolean {
  return ['png', 'webp', 'gif'].includes(this.originalFormat)
},
nLegacyFormat(): string {
  if (this.legacyFormat) {
    return this.legacyFormat
  }
  const formats: Record<string, string> = {
    webp: this.isTransparent ? 'png' : 'jpeg',
    svg: 'png'
  }
  return formats[this.nFormat] || this.originalFormat
},
const formats = this.nLegacyFormat !== this.nFormat
  ? [this.nLegacyFormat, this.nFormat]
  : [this.nFormat]

shadow81627 avatar Jul 16 '21 12:07 shadow81627

I'm really not an expert on this kind of logic. Would it be possible to test the mime type if the url has no extension?

narduin avatar Jul 16 '21 12:07 narduin

@pi0 I am thinking maybe a quick solution is to default to png when no extension is found in the url?

const formats: Record<string, string> = {
    webp: this.isTransparent || !this.originalFormat ? 'png' : 'jpeg',
    svg: 'png'
  }

There is also a more complicated solution of using a HEAD request to check mime type see stackoverflow for example.

getImgContentType (url) {
  return fetch(url, { method: 'HEAD' })
    .then(response => response.headers.get('Content-type'))
}

shadow81627 avatar Jul 16 '21 12:07 shadow81627

@narduin on a side note I checked the directus docs and saw the thumbnail generation might have potential for first party provider support in @nuxt/image. I could maybe look into creating such a provider if I get a test url.

example.com/thumper/assets/pnw7s9lqy68048g0?w=200&h=200&f=crop&q=80

shadow81627 avatar Jul 16 '21 13:07 shadow81627

@shadow81627

. I could maybe look into creating such a provider if I get a test url.

I can provide you one and help/test if you are still up for it?

vanling avatar Jul 13 '22 10:07 vanling

@vanling having a test/example/demo URL would be great for setting up a Directus image provider.

shadow81627 avatar Jul 13 '22 14:07 shadow81627

@shadow81627 will send you some details to your mail (from gh profile)

vanling avatar Jul 13 '22 14:07 vanling

@vanling I have created a pull request to add Directus as an image provider. https://github.com/nuxt/image/pull/572#issue-1306685670

shadow81627 avatar Jul 16 '22 02:07 shadow81627