Copy link to clipboard
Copied
Hello, mi format plugin loads a rgba image. I see it with transparency, that's ok, but when I go to the channels tab I only see 4 items (RGB, Red, Green and Blue).
How can I see the alpha channel of my file in the channel tab?
Thanks!
Copy link to clipboard
Copied
Alpha channels are always shown in the channels palette.
Are you confusing transparency(a strict subset tied to the color of each layer) with alpha channels (general use, the superset).
Copy link to clipboard
Copied
Probably I'm confusing transparency and alpha.
I set the gFormatRecord->planes = 4; (rgba), and fill the gFormatRecord->data with my buffers, but when I open an image in photoshop y get this:
The alpha channel is applied to the rgb channels ok, but the "Alpha 1" channel is black!
I set gFormatRecord->depth = 32 and gFormatRecord->imageMode = plugInModeRGB48 (RGB96 don't work with 32bit depth images (give me an error), I don't know why, but it is another problem).
Furthermore:
gFormatRecord->transparencyPlane = -1;
gFormatRecord->transparencyMatting = 0;
gFormatRecord->loPlane = 0;
gFormatRecord->hiPlane = 3;
Can I see the alpha channel to modify it and change the visibility of the rgb channels in consequence?
Copy link to clipboard
Copied
Yes, you told Photoshop to open an alpha channel, but never told Photoshop that the extra channel was supposed to be transparency (or how you may have matted the data).
> gFormatRecord->transparencyPlane = -1;
That means you have no transparency.
You are seeing the alpha channel in the channels palette.
And I'm not sure how you're getting transparency when you told Photoshop you have no transparency....
Copy link to clipboard
Copied
I set all layers configuration in DoReadStart function:
gFormatRecord->imageSize32.v = height;
gFormatRecord->imageSize32.h = width;
gFormatRecord->depth = IMAGE_DEPTH; // 32 bits
gFormatRecord->imageMode = plugInModeRGB48;
gFormatRecord->layerData = nLayers;
gFormatRecord->planes = 4; // RGBA.
gFormatRecord->loPlane = 0;
gFormatRecord->hiPlane = 3;
gFormatRecord->planeBytes = IMAGE_DEPTH >> 3;
gFormatRecord->rowBytes = imageSize.h * gFormatRecord->planes * ( IMAGE_DEPTH >> 3 );
gFormatRecord->colBytes = gFormatRecord->planes * ( IMAGE_DEPTH >> 3 );
gFormatRecord->transparencyPlane = -1;
gFormatRecord->transparencyMatting = 0;
gFormatRecord->imageHRes = FixRatio(72, 1);
gFormatRecord->imageVRes = FixRatio(72, 1);
gFormatRecord->theRect32.top = 0;
gFormatRecord->theRect32.left = 0;
gFormatRecord->theRect32.bottom = imageSize.v;
gFormatRecord->theRect32.right = imageSize.h;
gFormatRecord->blendMode = PIBlendLinearDodge;
gFormatRecord->isVisible = true;
Is missing any parameter to do it right?
When I fill the gformatrecord->data field, I do something like this (DoReadLayerContinue):
uint32 bufferSize = imageSize.v * gFormatRecord->rowBytes;
gFormatRecord->data = (void*)new byte[bufferSize];
for( int i = 0; i < nPixels; i++ )
{
((float*)gFormatRecord->data)[ i * 4 ] = ((float*)rgbBuffer)[ i * 3 ];
((float*)gFormatRecord->data)[ i * 4 + 1 ] = ((float*)rgbBuffer)[ i * 3 + 1 ];
((float*)gFormatRecord->data)[ i * 4 + 2 ] = ((float*)rgbBuffer)[ i * 3 + 2 ];
((float*)gFormatRecord->data)[ i * 4 + 3 ] = ((float*)alphaBuffer)[ i ];
}
The alpha channel is applied to the rgb channels (i see transparency like in the image above, and the "Layer 1" channel is black too. It seems that the transparencyPlane and Matting is ignored (I change matting to 1, 2... and the result is the same) and the blendMode and isVisible parameters are ignored too! (i set them to other values and it seems to take "PIBlendNormal" and "true" always).
Imagine that I need a 6 channel image, to mix these channels specially in a filter plugin made on my own. PS interpret all the extra channels (no rgb) as alpha! Can I manage more-than-4-channel images with potoshop, with or without alpha/transparency data?
Copy link to clipboard
Copied
Sorry, the "isVisible" parameter doesn't work in CS3, but it works in CS4 because is new for that version. "blendMode" is new for CS4 too but not work
Copy link to clipboard
Copied
Again: you are telling Photoshop that there is no transparency, and to open the fourth channel as a plain alpha channel.
If you want transparency, you have to tell Photoshop that the channel is supposed to be transparency (and how to handle any matting).
I still don't see how you got the results you showed -- because the code you gave will not open with transparency, and will open the fourth channel as an alpha channel.
Copy link to clipboard
Copied
As explained in the SDK: blendMode and isVisible are only going to apply if you are importing multiple layers.
And matting won't have any difference if you don't tell Photoshop that there is a transparency channel.
Somewhere, you have more code that you aren't giving (like specifying that one of the channels really is transparency) or you are leaving out other important details.
Photoshop just does what you tell it to do. And the code you've shown doesn't tell Photoshop to do what you say you want it to do, nor what you claim Phtosohop is doing.
Copy link to clipboard
Copied
OK, something must be wrong... but I don't find it!
That's my whole code (resumed). I ommit some code (saving file code (not used) or main function, where I only call te "DoSomething" functions. You can see that I use layers. The DoReadContinue function is only used to show the preview.
In the DoReadStart function I set the parameters for the layers (and the preview), and I fill the "data" and "layerName" params in the DoReadLayerContinue function. I hope you can understand the code!
...
const int32 IMAGE_DEPTH = 32;
...
SPBasicSuite * sSPBasic = NULL;
SPPluginRef gPluginRef = NULL;
FormatRecord * gFormatRecord = NULL;
intptr_t * gMxiInfoHandle = NULL;
MXIInfo* gMxiInfo = NULL;
int16 * gResult = NULL;
#define gCountResources gFormatRecord->resourceProcs->countProc
#define gGetResources gFormatRecord->resourceProcs->getProc
#define gAddResource gFormatRecord->resourceProcs->addProc
CmaxwellMXI* cMax;
///////////////////////////////////////////////////////////////////////////////
static void DoReadPrepare (void){
gFormatRecord->maxData = 0;
}
///////////////////////////////////////////////////////////////////////////////
static void DoReadStart(void){
char header[2];
ReadScriptParamsOnRead (); // override params here
if (*gResult != noErr) return;
// Read the file header
*gResult = SetFPos (gFormatRecord->dataFork, fsFromStart, 0);
if (*gResult != noErr) return;
ReadSome (sizeof( header ) * 2, &header);
if (*gResult != noErr) return;
// Check the magic number for avoid no-mxi files
int headerID = CheckIdentifier (header);
if( headerID != HEADER_MXI ) *gResult = formatCannotRead;
if (*gResult != noErr) return;
// The file is OK. Let's continue to obtain the data of the image.
cMax = new CmaxwellMXI( 0 );
strlen((char*)gFormatRecord->fileSpec->name);
gMxiInfo->filename = _strdup((char *)gFormatRecord->fileSpec->name + 1);
bool res = cMax->getMXIIInfo(
(const char*)gMxiInfo->filename,
gMxiInfo->width, gMxiInfo->height,
gMxiInfo->burn, gMxiInfo->monitorGamma, gMxiInfo->iso,
gMxiInfo->shutter, gMxiInfo->fStop, gMxiInfo->intensity,
gMxiInfo->scattering,
gMxiInfo->nMultilightChannels, gMxiInfo->lightNamesList,
gMxiInfo->availableBuffersMask,
gMxiInfo->widthPreview, gMxiInfo->heightPreview,
gMxiInfo->bufferPreview);
if(!res) return;
// Check the available extra buffers
int count = 0;
if( gMxiInfo->availableBuffersMask & CmaxwellMXI::ALPHA_BUFFER ){
// We will use that string to obtain later the desired extra buffer.
gMxiInfo->extraBuffersList[count] = "ALPHA";
gMxiInfo->hasAlpha = true;
count++;
}
else{
gMxiInfo->hasAlpha = false;
}
...
gMxiInfo->nExtraBuffers = count;
switch( IMAGE_DEPTH ){
case 8:
gMxiInfo->mode = plugInModeRGBColor;
break;
case 16:
gMxiInfo->mode = plugInModeRGB48;
break;
case 32:
gMxiInfo->mode = plugInModeRGB48; //96 gives me an error
break;
}
// SET UP THE DOCUMENT BASIC PARAMETERS.
VPoint imageSize;
if( gFormatRecord->openForPreview ){
// Preview always RGB8.
imageSize.v = gMxiInfo->heightPreview;
imageSize.h = gMxiInfo->widthPreview;
gFormatRecord->depth = 8;
gFormatRecord->imageMode = plugInModeRGBColor;
gFormatRecord->planes = 3;
gFormatRecord->loPlane = 0;
gFormatRecord->hiPlane = 2;
gFormatRecord->colBytes = 3;
gFormatRecord->rowBytes = imageSize.h * gFormatRecord->planes;
gFormatRecord->planeBytes = 1;
}
else{
// Configure the layers. All RGBA32.
imageSize.v = gMxiInfo->height;
imageSize.h = gMxiInfo->width;
gFormatRecord->depth = IMAGE_DEPTH;
gFormatRecord->imageMode = gMxiInfo->mode;
gFormatRecord->layerData =
2 + gMxiInfo->nMultilightChannels + gMxiInfo->nExtraBuffers;
gFormatRecord->planes = 4; // RGBA.
gFormatRecord->loPlane = 0;
gFormatRecord->hiPlane = 3;
gFormatRecord->planeBytes = IMAGE_DEPTH >> 3;
gFormatRecord->rowBytes = imageSize.h * gFormatRecord->planes * ( IMAGE_DEPTH >> 3 );
gFormatRecord->colBytes = gFormatRecord->planes * ( IMAGE_DEPTH >> 3 );
gFormatRecord->transparencyPlane = 3;
gFormatRecord->transparencyMatting = 1;
gFormatRecord->blendMode = PIBlendLinearDodge;
gFormatRecord->isVisible = true;
}
SetFormatImageSize(imageSize);
gFormatRecord->imageHRes = FixRatio(72, 1);
gFormatRecord->imageVRes = FixRatio(72, 1);
VRect theRect;
theRect.left = 0;
theRect.right = imageSize.h;
theRect.top = 0;
theRect.bottom = imageSize.v;
SetFormatTheRect(theRect);
// No resources for now.
if (sPSHandle->New != NULL) gFormatRecord->imageRsrcData = sPSHandle->New(0);
gFormatRecord->imageRsrcSize = 0;
return;
}
///////////////////////////////////////////////////////////////////////////////
///
/// Called for prewiew only.
///
///////////////////////////////////////////////////////////////////////////////
static void DoReadContinue (void){
// Dispose of the image resource data if it exists.
DisposeImageResources ();
if( gFormatRecord->openForPreview ){
VPoint imageSize = GetFormatImageSize();
gFormatRecord->data = gMxiInfo->bufferPreview;
if (*gResult == noErr) *gResult = gFormatRecord->advanceState();
if( gFormatRecord->data != NULL ){
delete[] (Crgb8*)gMxiInfo->bufferPreview;
gMxiInfo->bufferPreview = NULL;
gFormatRecord->data = NULL;
}
}
// De momento nos olvidamos de los icc profiles [TODO]
//DoReadICCProfile ();
}
///////////////////////////////////////////////////////////////////////////////
static void DoReadFinish (void)
{
// Dispose of the image resource data if it exists.
DisposeImageResources ();
WriteScriptParamsOnRead (); // should be different for read/write
// write a history comment
AddComment ();
// Clean some memory.
if( gMxiInfo->lightNamesList != NULL ){
for( unsigned int i = 0; i < gMxiInfo->nMultilightChannels; i++){
if( gMxiInfo->lightNamesList != NULL ){
delete[] gMxiInfo->lightNamesList;
gMxiInfo->lightNamesList = NULL;
}
}
delete[] gMxiInfo->lightNamesList;
gMxiInfo->lightNamesList = NULL;
}
if( gMxiInfo->bufferPreview != NULL ){
delete[] gMxiInfo->bufferPreview;
gMxiInfo->bufferPreview = NULL;
}
if( gMxiInfo->filename != NULL ){
delete[] gMxiInfo->filename;
gMxiInfo->filename = NULL;
}
if( cMax != NULL ){
delete cMax;
cMax = NULL;
}
}
///////////////////////////////////////////////////////////////////////////////
static void DoReadLayerStart(void){
// empty
}
///////////////////////////////////////////////////////////////////////////////
static void DoReadLayerContinue (void){
int32 done;
int32 total;
VPoint imageSize = GetFormatImageSize();
// Set the progress bar data
done = gFormatRecord->layerData + 1;
total = gMxiInfo->nMultilightChannels + gMxiInfo->nExtraBuffers + 2;
// Dispose of the image resource data if it exists.
DisposeImageResources ();
uint32 bufferSize = imageSize.v * gFormatRecord->rowBytes;
int nPixels = gMxiInfo->width * gMxiInfo->height;
char* lightName = NULL;
// SET THE BLACK BACKGROUND
if( gFormatRecord->layerData == 0 ){
gFormatRecord->data = (void*)new byte[bufferSize];
for( int i = 0; i < nPixels; i++ ){
((float*)gFormatRecord->data)[ i * 4 ] =
((float*)gFormatRecord->data)[ i * 4 + 1 ] =
((float*)gFormatRecord->data)[ i * 4 + 2 ] = 0.0;
((float*)gFormatRecord->data)[ i * 4 + 3 ] = 1.0;
}
// Set the layer name.
gFormatRecord->layerName = new uint16[64];
gFormatRecord->layerName[0] = 'B';
gFormatRecord->layerName[1] = 'a';
gFormatRecord->layerName[2] = 'c';
gFormatRecord->layerName[3] = 'k';
gFormatRecord->layerName[4] = 'g';
gFormatRecord->layerName[5] = 'r';
gFormatRecord->layerName[6] = 'o';
gFormatRecord->layerName[7] = 'u';
gFormatRecord->layerName[8] = 'n';
gFormatRecord->layerName[9] = 'd';
gFormatRecord->layerName[10] = '\0';
}
// LOAD THE LIGHT LAYERS
else if( gFormatRecord->layerData < gMxiInfo->nMultilightChannels + 1 ){
void* lightBuffer = NULL;
void* alphaBuffer = NULL;
byte foob;
dword food;
// Get the light buffer.
bool res = cMax->getLightBuffer(
(char*)gMxiInfo->filename,
gFormatRecord->layerData - 1, IMAGE_DEPTH,
lightBuffer,
gMxiInfo->width, gMxiInfo->height, lightName);
if(!res){
*gResult = readErr;
return;
}
if( gMxiInfo->hasAlpha ){
// Get the alpha buffer.
res = cMax->getExtraBuffer(
(char*)gMxiInfo->filename,
"ALPHA", IMAGE_DEPTH, alphaBuffer,
food, food, foob);
if(!res){
*gResult = readErr;
return;
}
}
else{
alphaBuffer = (void*)new float[ gMxiInfo->width * gMxiInfo->height * 3 ];
for( int i = 0; i < nPixels; i++ ){
// Only need to set the red channel.
((float*)alphaBuffer)[ i * 3 ] = 1.0;
}
}
// Put them together.
gFormatRecord->data = (void*)new byte[bufferSize];
for( int i = 0; i < nPixels; i++ ){
((float*)gFormatRecord->data)[ i * 4 ] = ((float*)lightBuffer)[ i * 3 ];
((float*)gFormatRecord->data)[ i * 4 + 1 ] = ((float*)lightBuffer)[ i * 3 + 1 ];
((float*)gFormatRecord->data)[ i * 4 + 2 ] = ((float*)lightBuffer)[ i * 3 + 2 ];
((float*)gFormatRecord->data)[ i * 4 + 3 ] = ((float*)alphaBuffer)[ i * 3 ];
}
delete[] (float*)lightBuffer;
delete[] (float*)alphaBuffer;
// Set the layer name.
...
}
//LOAD THE EXTRA CHANNELS
if( ... ){
...
}
//READ THE RENDER BUFFER
if( ... ){
...
}
// User can abort.
if (gFormatRecord->abortProc()){
*gResult = userCanceledErr;
return;
}
...
// Commit the layer.
if (*gResult == noErr) *gResult = gFormatRecord->advanceState();
// Update the progress bar.
(*gFormatRecord->progressProc)( done, total );
// Free memory.
if( gFormatRecord->data != NULL ){
delete[] (float*)gFormatRecord->data;
gFormatRecord->data = NULL;
}
if( lightName != NULL ){
delete[] lightName;
lightName = NULL;
}
}
///////////////////////////////////////////////////////////////////////////////
static void DoReadLayerFinish (void)
{
// Nothing to do.
}
///////////////////////////////////////////////////////////////////////////////
...
And that's the image that I obtain loading a 8 layer image:
The layers have transparency (when I set "transparencyPlane" to -1, or 0, or 1, or 2, or 3, or 4....., I got the same result!). The blending mode is still "normal". I had set it to "linear dodge" The "isVisible" param works OK.
Alpha 1 is still black.
Is possible that I need to set something in the .r file? I had to add "FormatLayerSupport { doesSupportFormatLayers }," to manage layers, for instance.
Copy link to clipboard
Copied
OK, so you are loading layer transparency correctly.
But it looks like you are also loading an extra alpha channel (solid black) in addition to the layers.
I'm really not sure where that is coming from.
Sorry that our layer reading code hasn't been well tested - it got hacked in for a special purpose and then sort of escaped...
And I'm not sure how your alpha buffer takes every third value - but maybe it has other data in there as well.
Sigh. I have a feeling I'm just going to have to debug our code.
Copy link to clipboard
Copied
Finally I don't want to apply the alpha channel to the rgb channels. I mean that I want the channels red, green, blue, alpha (and one or two more) in every layer, but I don't want the rgb channels to be premultiplied with the alpha channel(s). Is this possible?
Sorry for the inconvenience. Good luck with the debugging!
Copy link to clipboard
Copied
Photoshop is never premultiplied.
But if you want transparency per layer, it has to be as transparency.
Alpha channels are per document, not per layer.
It looks like you're already displaying the result correctly (with transparency showing as transparency).
Copy link to clipboard
Copied
I don't want transparency. I need some "extra" channels besides rgb. Alpha data, shadow data, and maybe others like z-buffer... so OK, I need these channels to be common to all layers, but I dont want transparency, and PS looks like to apply transparency always....
Copy link to clipboard
Copied
PS shows you transparency when you supply data with transparency.
Your code specified transparency, and supplied transparency data -- Photoshop is just showing you what you gave it.
As for the z buffer and other non-layer data channels: just load them as alpha channels.
Copy link to clipboard
Copied
If I load them as alpha channels, a transparency is applied.
I explain myself. I allocate memory for gformatrecord->data to save RGBAX image (X can be whatever). Well, I set the RGB components with the image data, I set the A component to 1.0 (all pixels) and the X component to 0.0. The image result is fully transparent . I set gFormatRecord->transparencyPlane = 3;
If I set the X channel to 1.0 and the A channel to 0.0, the image is not transparent. So, is the last alpha channel used for transparency?
Copy link to clipboard
Copied
Um, no. If you load them as alpha channels, they come in as alpha channels -- unassociated with any layer, and can't be transparency.
Your code specifies that the fourth channel is transparency and loaded per layer, so Photoshop uses that data as transparency.
You didn't load them as alpha channels. You loaded them as transparency -- and that appears to be correct, because they are transparency and NOT arbitrary alpha channels.
It still seems like you are confusing alpha channels with transparency.
And transparency is not going to show up in the channels palette, because transparency is closely connected to the pixel data for each layer.
Copy link to clipboard
Copied
Well, I'm using transparency, forget alpha.
I use 10 channels per layer, and the parameter gFormatRecord->transparencyPlane is set to 3, but the plane that photoshop use as transparency is the 10th (the last plane). Is this behaviour correct?
Layer N
Channel 1 (R)
Channel 2 (G)
Channel 3 (B)
Channel 4 (Alpha1)
...
Channel 10 (alpha7) ->used as a transparency although gFormatRecord->transparencyPlane = 3;
Anyway, the fact that the last channel is used as a transparency always is not a problem for me, but it looks like a bug.
Copy link to clipboard
Copied
Last channel as transparency: Yeah, that does look like a bug.
As for 10 channels per layer: Photoshop can't do that. Each layer only has color channels, transparency, and an optional user mask.
Copy link to clipboard
Copied
If each layer only has color channels, transparency and optional user mask... why the sdk allows me to use until 24 channels?
Copy link to clipboard
Copied
Because the SDK is for general file import, and FILES can have more alpha channels.
The Layer support was hacked in, and still can't provide anything more than layers in the application really support.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now