Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Artefacts with transparency in png drawing #3624

Closed
2 of 11 tasks
artygrand opened this issue Jun 28, 2023 · 5 comments · Fixed by #3627
Closed
2 of 11 tasks

Artefacts with transparency in png drawing #3624

artygrand opened this issue Jun 28, 2023 · 5 comments · Fixed by #3627

Comments

@artygrand
Copy link

This is:

What is the expected behavior?

In excel I can insert png image with transparency without problems

What is the current behavior?

Problem is artefacts in transparent background, like in example below. This is one file made from 2 in Photoshop.
Absolutely opaque, with grey zones.

image

What are the steps to reproduce?

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

<?php

require __DIR__ . '/vendor/autoload.php';

// Create new Spreadsheet object
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

$sheet = $spreadsheet->getActiveSheet();

$stamp = MemoryDrawing::fromString($stamp_file);
$stamp->setName('Stamp');
$stamp->setHeight(120);
$stamp->setCoordinates('A2');
$stamp->setWorksheet($sheet);

$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save($path);

If this is an issue with reading a specific spreadsheet file, then it may be appropriate to provide a sample file that demonstrates the problem; but please keep it as small as possible, and sanitize any confidential information before uploading.

What features do you think are causing the issue

  • Reader
  • Writer
  • Styles
  • Data Validations
  • Formula Calculations
  • Charts
  • AutoFilter
  • Form Elements

Does an issue affect all spreadsheet file formats? If not, which formats are affected?

Which versions of PhpSpreadsheet and PHP are affected?

PhpSpreadsheet 1.28
PHP 8.1

@oleibman
Copy link
Collaborator

You do not show how you arrived at the value in $stamp_file. Please compare your code to the following:

        $stamp_file = file_get_contents('issue.3624.png'); // the file you uploaded above
        $stamp = PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::fromString($stamp_file);

Or, more simply (use drawing as-is rather than as memory drawing):

        $stamp = new PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
        $stamp->setPath('issue.3624.png');

In either case, the result appears to be exactly the same as if I had added the drawing directly in Excel (adjusting the height appropriately). If your results differ, please show how.

Excel:
image

PhpSpreadsheet:
image

@artygrand
Copy link
Author

artygrand commented Jun 30, 2023

@oleibman , my attachment isn't original picture, but the broken result
I use it with laravel S3 Storage, so I can get only as string (I don't want to copy it on server and then wipe)

Okay, I tested different approaches and looks like found the bug. Lets try these 3 snippents

file_get_contents with storage path

$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

$stamp = PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::fromString(file_get_contents(storage_path('app/test.png')));
$stamp->setName('Stamp');
$stamp->setHeight(120);
$stamp->setCoordinates('A2');
$stamp->setWorksheet($sheet);

$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save(storage_path('app/res-fgc.xlsx'));

Storage getter, that I use. It is almost file_get_contents

$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

$stamp = PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::fromString(Storage::disk('local')->get('test.png'));
$stamp->setName('Stamp');
$stamp->setHeight(120);
$stamp->setCoordinates('A2');
$stamp->setWorksheet($sheet);

$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save(storage_path('app/res-stor.xlsx'));

Not memory drawing but base

$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

$stamp = new PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$stamp->setPath(storage_path('app/test.png'));
$stamp->setName('Stamp');
$stamp->setHeight(120);
$stamp->setCoordinates('A2');
$stamp->setWorksheet($sheet);

$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save(storage_path('app/res-path.xlsx'));

Original picture:
test

Results:
res-fgc.xlsx
res-stor.xlsx
res-path.xlsx

Drawing with path
image

MemoryDrawing is absolutely broken
image

Where is alpha channel?

@oleibman
Copy link
Collaborator

Thank you, I am now able to duplicate your problem. However, I believe the problem lies in Php, not in PhpSpreadsheet.

        $stamp_file = file_get_contents('issue.3624b.png'); // your new image
        $gdImage = imagecreatefromstring($stamp_file);
        imagepng($gdImage, 'issue.3624c.png');

This code snippet, which does not use PhpSpreadsheet at all, shows that its output file does not match the input file (and, in fact, matches your 'bad' image). When I substitute your original input file, the output file does match it, so I believe this code is correct, and therefore that one or both of the native Php functions imagecreatefromstring or imagepng has a problem. For the record, specifying PNG_NO_FILTER or PNG_ALL_FILTERS on the imagepng call does not change anything.

@oleibman
Copy link
Collaborator

I have opened an issue with Php.

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Jul 1, 2023
Fix PHPOffice#3624. Use the same logic as elsewhere in the same module to invoke `imagesavealpha` when appropriate. (I confess that I do not understand the use case where you would not use imagesavealpha.) The fix was easy; writing a test was not. Google to the rescue.
@oleibman
Copy link
Collaborator

oleibman commented Jul 3, 2023

From the Php issue, an extra call was suggested (imagesavealpha). I will create a PR to incorporate this suggestion into PhpSpreadsheet. Look for it in a day or two.

oleibman added a commit that referenced this issue Jul 3, 2023
Fix #3624. Use the same logic as elsewhere in the same module to invoke `imagesavealpha` when appropriate. (I confess that I do not understand the use case where you would not use imagesavealpha.) The fix was easy; writing a test was not. Google to the rescue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants