Skip to content

QRGdImage (custom): mime type is not properly set in base64 output #223

Open
@codemasher

Description

@codemasher

Issue

Currently there is an issue with custom output classes based on QRGdImage where the mime type of the base64 output is not properly set to the image type but rather to "custom". This happens when a custom output class uses the optional base64 encoding as it is implemented in the method QRGdImage::dump() and is invoked via the QROptions settings:

$options->outputType      = QROutputInterface::CUSTOM;
$options->outputInterface = MyCustomOutput::class; // extends QRGdImage

The "imageWithLogo" example is affected by this issue (among others):

if($this->options->outputBase64){
$imageData = $this->toBase64DataURI($imageData, 'image/'.$this->options->outputType);
}

The resulting output would not properly display and looks similar to the following:

data:image/custom;base64,<encoded image data>

Further, this issue will always output the image as PNG as this is the default in the switch that determines the GD output function.

Affected versions

Affected by this issue are all versions of php-qrcode since optional base64 encoding was introduced: v3.x, v4.x and the upcoming v5.x.

Workaround

There are several workarounds available, one of which is already provided in the above example, that is, manual invocation of the output class and setting QROptions::$outputType to the desired output type (setting to "custom" is not necessary in this case and will be ignored):

$qrcode = new QRCode($options);
$qrcode->addByteSegment('https://github.com');
$qrOutputInterface = new QRImageWithLogo($options, $qrcode->getQRMatrix());
// dump the output, with an additional logo
// the logo could also be supplied via the options, see the svgWithLogo example
$out = $qrOutputInterface->dump(null, __DIR__.'/octocat.png');

Another workaround could be to hardcode the output or mime type:

class MyCustomOutput extends QRGdImage{

	public function dump(string $file = null):string{
		// override the QROptions setting...
		$this->options->outputType = $this::GDIMAGE_PNG;
		
		// ...

		$imageData = $this->dumpImage();

		// ...or hard code the mime type
		if($this->options->outputBase64){
			$imageData = $this->toBase64DataURI($imageData, 'image/png');
		}
	
		return $imageData;
	}

}

Proposed fix

Since this is a low priority issue that can be easily worked around, v3.x and v4.x will not receive any fixes for it. For v5.x i will introduce separate classes for the several QRGdImage output types, such as QRGdImagePNG and so on. In v6, the class QRGdImage will be made abstract.

The base output class QROutputAbstract will see the addition of an internal constant MIME_TYPE that will set the type for the current class and which will be called in QROutputAbstract::toBase64DataURI().

Further, the setting QROptions::$outputType will be deprecated in favor of QROptions::$outputInterface, which in turn will also make calling custom classes easier.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions