这是indexloc提供的服务,不要输入任何密码
Skip to content

Improve source size calculation used by copyExternalImageToTexture with HTMLImageElement #5097

@teoxoy

Description

@teoxoy

The spec says implementations should use: naturalWidth, naturalHeight (added in #4366).

Those attributes return density-corrected natural width/height if available or 0 if not.

Do note that "density-corrected natural width/height" is not just natural dimensions width/height divided by current pixel density. If the image has preferred density-corrected dimensions (extracted from EXIF metadata), those will get used instead.

CanvasRenderingContext2D.drawImage() behavior

@kainino0x mentioned we should use the same algorithm as CanvasRenderingContext2D.drawImage() #4256 (comment) which is:

If the sx, sy, sw, and sh arguments are omitted, then they must default to 0, 0, the image's natural width in image pixels, and the image's natural height in image pixels, respectively. If the image has no natural dimensions, then the concrete object size must be used instead, as determined using the CSS "Concrete Object Size Resolution" algorithm, with the specified size having neither a definite width nor height, nor any additional constraints, the object's natural properties being those of the image argument, and the default object size being the size of the output bitmap. [CSSIMAGES]

from https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-drawimage

The confusing part:

  • "The term natural dimensions refers to the set of the natural height, natural width, and natural aspect ratio (the ratio between the width and height), each of which may or may not exist for a given object."
  • drawImage() says that "If the image has no natural dimensions, then the concrete object size must be used instead...". No natural dimensions means no natural height, no natural width, and no natural aspect ratio.
  • The "Concrete Object Size Resolution" algorithm when "called" with the arguments specified by drawImage() can be simplified to just: return the size of the output bitmap.

So, algorithm used by drawImage() boils down to:

  • if present(natural width) && present(natural height): return (natural width, natural height)
  • if !present(natural width) && !present(natural height) && !present(natural aspect ratio): return output bitmap size
  • what about the other permutations?

If the text said: "If the image has no natural width or no natural height, then the concrete object size must be used instead...", then it would boil down to:

  • the natural aspect ratio could be used to derive the missing dimension,
  • if both dimensions are missing:
    • if the object has a natural aspect ratio: return the size of the largest rectangle that has the object’s natural aspect ratio that also fits inside the output bitmap,
    • otherwise: return the size of the output bitmap

(as per Concrete Object Size Resolution).

I assume that that was the intent.

What should be our behavior?

I think it should be:

Note that drawImage() doesn't take into account current pixel density which I think is correct.

Do we need to use preferred density-corrected dimensions if available?

@emilio mentioned that there can be SVG images that only have a natural aspect ratio. How should we handle those?

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiWebGPU API

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions