Jump to content
You must now use your email address to sign in [click for more info] ×

Stop the Alpha layer from saving destructively.


Recommended Posts

For whatever reason. Saving a png with an alpha layer actively deletes the pixels that were made transparent by the alpha layer.

I'm well aware the point of an alpha layer at least traditionally is transparency. But if I save a PNG in Photoshop with an alpha layer, I can open that image in any editor and enable or disable the alpha layer at will in order to show the parts of the image that were made transparent. In Affinity Photo, when I save with an alpha layer, any pixels that were made transparent are actively deleted from the main layers, meaning that there is just an empty black spot where the alpha layer is if you decide to disable the alpha layer.

 

This makes absolutely no sense given Photo 2's emphasis on non-destructive editing. I understand that it might save on file size, however for that kind of decision it should be at the very least in the export dialog. I need to keep the data that was made transparent by the alpha layer, I don't want it deleted, I just want it hidden until I choose to unhide it again. Unfortunately yet another thing that puts Photoshop ahead for the moment, that I'm hoping is fixed.

Link to comment
Share on other sites

This was discussed at length for v1 and does not appear to have changed, so if you are not familiar, you might want to go back and look at that thread.

This effect is not happening when exporting.  From a few experiments I had done in the past (and a shorter variation just now), as far as I can tell, the Affinity suite pre-multiplies alpha information within the document itself, so the data is not just being "thrown away" when exporting, but multiplied by zero (thus made black) when alpha is zero, during editing.  As a consequence it is no longer present in the document when exporting.

Link to comment
Share on other sites

Well that sucks to hear. Good to know the technical information behind it, although I really hope it changes at some point. This issue combined with not being able to paste directly into an alpha channel makes dealing with the alpha channels really obnoxious at the moment. I know there are ways around pasting into an alpha channel but unfortunately no way to fix the black spots

Link to comment
Share on other sites

As a workaround: don’t use the inherent alpha channel of pixel layers.

you can create a separate mask layer from the mask in the pixel layer, and the fill the alpha channel.

As long as you keep the alpha as separate mask, nothing gets zeroed out.

@fde101 And I don’t think it is premultiplied alpha, it is simply part of the engine to explicitly zero out RGB color channels when alpha becomes zero. You can set alpha to 1/255. if premultiplied alpha would be used, the color information would be clipped, which is not the case. RGB values stay constant for any alpha value from 1/255 to 255/255. 

Again and again: RGB ist Not zeroed during import / export (when done correctly using separate mask layer). RGB colors can be recovered by filling the alpha channel after import.

RGB gets zeroed when the inherent alpha value of the RGB layer gets to 0 within the document.

 

 

Mac mini M1 A2348 | Windows 10 - AMD Ryzen 9 5900x - 32 GB RAM - Nvidia GTX 1080

LG34WK950U-W, calibrated to DCI-P3 with LG Calibration Studio / Spider 5

iPad Air Gen 5 (2022) A2589

Special interest into procedural texture filter, edit alpha channel, RGB/16 and RGB/32 color formats, stacking, finding root causes for misbehaving files, finding creative solutions for unsolvable tasks, finding bugs in Apps.

My posts focus on technical aspects and leave out most of social grease like „maybe“, „in my opinion“, „I might be wrong“ etc. just add copy/paste all these softeners from this signature to make reading more comfortable for you. Otherwise I’m a fine person which respects you and everyone and wants to be respected.

 

Link to comment
Share on other sites

3 minutes ago, NotMyFault said:

if premultiplied alpha would be used, the color information would be clipped

You seem to be assuming integer math.  With floating-point math there is plenty of precision in 32-bit color values (which I suspect is being used internally, possibly one of the reasons for the seemingly large sizes of the .afphoto files?) to retain the original color information from 8-bit and probably even 16-bit per element colors when multiplied by low opacities that are still greater than zero.

Link to comment
Share on other sites

1 hour ago, fde101 said:

You seem to be assuming integer math.  With floating-point math there is plenty of precision in 32-bit color values (which I suspect is being used internally, possibly one of the reasons for the seemingly large sizes of the .afphoto files?) to retain the original color information from 8-bit and probably even 16-bit per element colors when multiplied by low opacities that are still greater than zero.

RBG/8 has 8 bits per colour (and alpha) channel to store data, or 256 distinguishable values.

RBG/16 has 16 bits per colour (and alpha) channel to store data, or 65536 distinguishable values.

Both using integer (positive only) to store values. You can use procedural texture filters to verify my claims. The layers can store exactly 256 or 65536 different values. They are normalised to the 0.0 to 1.0 range for display purposes. Calculations are integer, not float. for RBG/8, you get exactly 256 different values in steps of 1/256, from 0.0 to 1.0 (I use only 1 decimal). The values are actually binary 00000000, 000001, 00000010, ... 11111111 and interpreted accordingly on the fly. No float is used, no exponent.

Color values can be shown in UI as 0-255 (color panel), 0-100% (color panel, info picker), 0.0-1.0 (procedural texture filter).

If you use %, the UI becomes a bit strange, as no exact conversion from 256 step into % using 1% steps is not possible. So you get some percent values, and can nudge them up or down a step. The % value stays in UI, but the stored value gets 1/255 up or down.

RGB/32 uses 32 bits, and short floats. Affinity calls this "unbound", as no normalisation to 0.0 to 1.0 is used. But the UI limits the range to 0.0 to 100.0, cutting out negative and larger values.

 

Mac mini M1 A2348 | Windows 10 - AMD Ryzen 9 5900x - 32 GB RAM - Nvidia GTX 1080

LG34WK950U-W, calibrated to DCI-P3 with LG Calibration Studio / Spider 5

iPad Air Gen 5 (2022) A2589

Special interest into procedural texture filter, edit alpha channel, RGB/16 and RGB/32 color formats, stacking, finding root causes for misbehaving files, finding creative solutions for unsolvable tasks, finding bugs in Apps.

My posts focus on technical aspects and leave out most of social grease like „maybe“, „in my opinion“, „I might be wrong“ etc. just add copy/paste all these softeners from this signature to make reading more comfortable for you. Otherwise I’m a fine person which respects you and everyone and wants to be respected.

 

Link to comment
Share on other sites

On 12/12/2022 at 4:34 AM, ThatVeryHooniz said:

But if I save a PNG in Photoshop with an alpha layer, I can open that image in any editor and enable or disable the alpha layer at will in order to show the parts of the image that were made transparent.

Like this?

Alpha.png.1c61f65f3e6bd0b7e0048e2e1fff5e1d.png

I used A.Photo v1.

Link to comment
Share on other sites

2 hours ago, NotMyFault said:

RBG/8 has 8 bits per colour (and alpha) channel to store data, or 256 distinguishable values.

...

I am a computer software engineer by trade, so I am well aware of how the math works.

What was not clear to me is whether or not the .afphoto files and the internal processing of the Affinity apps were actually storing 8-bit or 16-bit integers, or simply using that as a a basis for color presentation and for import/export purposes, and actually functioning on 32-bit floating-point values internally.

Whatever the case, some experimentation I just did does seem to bear out that an RGB/8 document actually is storing RGB/8 and working with it between adjustment filters, so it would stand to reason that the values are most likely not being pre-multiplied, as you had suggested.

In the case that they are not pre-multiplied, the fact that we are losing the data on the zero-alpha pixels does seem rather arbitrary.

Link to comment
Share on other sites

2 hours ago, fde101 said:

am a computer software engineer by trade, so I am well aware of how the math works.

Then you should be aware of the performance and storage impact 8 bit integer vs. 32 bit float for RAM, CPU, GPU

2 hours ago, fde101 said:

What was not clear to me is whether or not the .afphoto files and the internal processing of the Affinity apps were actually storing 8-bit or 16-bit integers

They do.

2 hours ago, fde101 said:

or simply using that as a a basis for color presentation and for import/export purposes, and actually functioning on 32-bit floating-point values internally.

That would not make any sense wrt to RAM usage, and performance impact, etc. You can very simply prove that every layer blend operation produces results that are clipped at 8 bit values (For RGB/8)

Just add a levels adjustment which reduces the luminosity by 50%, then add a reverse adjustment doubling luminosity. The lowest bit will be gone, you get increased banding (lower part). If you double the strength (factor 2, 4, 8, ..) you will loose another bit for every doubling.

If you "theory" of 32 bit float would apply, no bits would be lost.

 

1397421764_Screenshot2022-12-16at23_30_48.thumb.png.1accf4d973da1f4eaf5075683b1e37d7.png

 

 

Mac mini M1 A2348 | Windows 10 - AMD Ryzen 9 5900x - 32 GB RAM - Nvidia GTX 1080

LG34WK950U-W, calibrated to DCI-P3 with LG Calibration Studio / Spider 5

iPad Air Gen 5 (2022) A2589

Special interest into procedural texture filter, edit alpha channel, RGB/16 and RGB/32 color formats, stacking, finding root causes for misbehaving files, finding creative solutions for unsolvable tasks, finding bugs in Apps.

My posts focus on technical aspects and leave out most of social grease like „maybe“, „in my opinion“, „I might be wrong“ etc. just add copy/paste all these softeners from this signature to make reading more comfortable for you. Otherwise I’m a fine person which respects you and everyone and wants to be respected.

 

Link to comment
Share on other sites

Just now, NotMyFault said:

Then you should be aware of the performance and storage impact 8 bit integer vs. 32 bit float for RAM, CPU, GPU

They do.

That would not make any sense wrt to RAM usage, and performance impact, etc. You can very simply prove that every layer blend operation produces results that are clipped at 8 bit values (For RGB/8)

Just add a levels adjustment which reduces the luminosity by 50%, then add a reverse adjustment doubling luminosity. The lowest bit will be gone, you get increased banding (lower part). If you double the strength (factor 2, 4, 8, ..) you will loose another bit for every doubling.

If you "theory" of 32 bit float would apply, no bits would be lost.

 

1397421764_Screenshot2022-12-16at23_30_48.thumb.png.1accf4d973da1f4eaf5075683b1e37d7.png

 

 

I can encode any 8-bit value as color in one color channel RGB/8, and 16 bit value as color in RGB/16, and provide filters which proof correct storage. Or you can use the info panel (limited to 8 bit unfortunately) to verify my claims. And you can't store more than 8 bit values within RGB/8 documents. 

Mac mini M1 A2348 | Windows 10 - AMD Ryzen 9 5900x - 32 GB RAM - Nvidia GTX 1080

LG34WK950U-W, calibrated to DCI-P3 with LG Calibration Studio / Spider 5

iPad Air Gen 5 (2022) A2589

Special interest into procedural texture filter, edit alpha channel, RGB/16 and RGB/32 color formats, stacking, finding root causes for misbehaving files, finding creative solutions for unsolvable tasks, finding bugs in Apps.

My posts focus on technical aspects and leave out most of social grease like „maybe“, „in my opinion“, „I might be wrong“ etc. just add copy/paste all these softeners from this signature to make reading more comfortable for you. Otherwise I’m a fine person which respects you and everyone and wants to be respected.

 

Link to comment
Share on other sites

1 minute ago, NotMyFault said:

That would not make any sense wrt to RAM usage, and performance impact, etc.

Many modern computer processors (including the ARM processors used in Apple Silicon systems) are not designed to operate directly on 8-bit integers, but always convert them to larger integers before operating on them.  In terms of performance impact the biggest gain from using smaller numbers would come from how much data could be held in cache while working on it, and the benefits of that will vary depending on the operation if you start working with images that are larger than can fit in cache (which can easily happen even in RGB/8 with the resolutions of modern cameras).

That said, applications such as Affinity Photo are trying to do more of their image manipulations in the GPU rather than the CPU, and most GPUs do not handle integer arithmetic very efficiently (some of them can do basic integer operations, but many less basic operations are "faked" using floating-point techniques, and performance suffers as a result of the way this is handled).  In order to make the best use of a GPU, it would often be necessary to convert the stored integers into a floating-point format before processing them.  If that conversion is done for every operation, there would be a clear trade-off between the cost of performing the conversion and the benefits of the lowered memory use (as you would now need to hold the unconverted and the converted copies in memory during the conversion in each direction).

Some of the operations that the image filters perform will simply be more efficient when working in floating-point, so it very well might make a lot of sense to hold the image data in floating-point format while it is being worked on, particularly if there is a stack of multiple consecutive filters being applied - but that does not seem to be what they are actually doing.

 

13 minutes ago, NotMyFault said:

Just add a levels adjustment which reduces the luminosity by 50%, then add a reverse adjustment doubling luminosity

Yes, I did something similar to this earlier when I was testing to see how the processing was likely being done, hence from my earlier reply:

2 hours ago, fde101 said:

some experimentation I just did does seem to bear out that an RGB/8 document actually is storing RGB/8 and working with it between adjustment filters

 

I don't know exactly how the engine is set up within the Affinity apps, so I don't know if they are indeed converting the color values to FP on the fly as they work with them (and back - which means that each adjustment operation would potentially be another set of redundant conversions) or actually faking some things out with integer data, but in any case the results I am seeing from the experiments do suggest that they are at least storing the data in the requested format when in between those filters.

Link to comment
Share on other sites

It might be possible that Affinity converts the 8 bits into a temporary float for layer blending. but his is not relevant, as long as the result of every blend operation is converted back into a 8 bit number, where 0000000 stays for 0.00 and 11111111 stays for 1.00 and every number in between uses 1/255 of the full range. And all what I can see is that every pixel layer and every blend operation does work in this way.

 

Mac mini M1 A2348 | Windows 10 - AMD Ryzen 9 5900x - 32 GB RAM - Nvidia GTX 1080

LG34WK950U-W, calibrated to DCI-P3 with LG Calibration Studio / Spider 5

iPad Air Gen 5 (2022) A2589

Special interest into procedural texture filter, edit alpha channel, RGB/16 and RGB/32 color formats, stacking, finding root causes for misbehaving files, finding creative solutions for unsolvable tasks, finding bugs in Apps.

My posts focus on technical aspects and leave out most of social grease like „maybe“, „in my opinion“, „I might be wrong“ etc. just add copy/paste all these softeners from this signature to make reading more comfortable for you. Otherwise I’m a fine person which respects you and everyone and wants to be respected.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.