Copy link to clipboard
Copied
Hi all,
I would like to know if there is a method in to make a PNG from a pixel data.
My plugin is iterating through raster objects, accessing slices of pixels, and will make pngs of this slices.
in AIImageOptSuite, there is a method to make a Png from an AIArtHandle.
Is there somewhere in a suite, a method to do that from a pixel data?
Any help will be appreciate.
Best regards,
Thomas.
Copy link to clipboard
Copied
I don't know if this is what you mean exactly, but we use the AIRasterizeSuite to rasterize artwork and export it as a PNG. If that's the kind of thing you're talking about I could take a look and see what's involved. I know we have some rather ugly looking blocks of code that do pixel conversion of some sort on the results to get it into a form we can write as a PNG, but its doable.
Copy link to clipboard
Copied
"but we use the AIRasterizeSuite to rasterize artwork and export it as a PNG"
This is what I do. But I've got a issue with embedded raster art.
For the moment this kind of art is re-rasterized, so resolution may be lost.
So, I wish I could access to pixel data of the raster image, and then could transform this into png, to avoid resolution issue.
If you have an anotther solution to fixe this issue, I'll take it too!
Best regards,
Thomas.
Copy link to clipboard
Copied
But using the Rasterize suite creates a kRasterArt -- shouldn't it be the same code to pull image data from that result as from an embedded image? I'm guessing its not, or you'd have done that already. I think I'm probably missing a step since I've yet to actually try exporting an existing raster (though I will probably have to before too long!).
Copy link to clipboard
Copied
I guess I'm not clear at all.
I can rasterize any kind of AIArtHandle and export it as an PNG image.
But there is a special case for kRasterArt.
- If the image is linked, I just male a copy of the linked image and then export it.
In that case, the exported image is exactly the same as the original one. Same resolution.
- If the image is embedded (not linked), i use the rasterize suite to get a raster.
But in this case, exported image could have a not the same resolution than the original image.
What iI would like to do, is to use the pixel data from the embedded image (pixel data) and create a png, in
order to have an exported image identical to the original one.
I hope being clear, despite the fact my english is not fluent.
Regards,
Thomas.
Copy link to clipboard
Copied
No, I think you're pretty clear but there's still something I'm not understanding. What call in AIRasterize are you using? When I use it, I get an AIArtHandle ('AIArtHandle *raster' is the parameter name) which represents a raster object on the artboard. We then crack that open using AIRasterSuite::GetRasterInfo() and use that to write out a PNG.
Maybe you're skipping a step. Are you rasterizing other kinds of art straight to disk using the AIImageOptSuite? I've never used that suite, so maybe you're doing skipping a step I assumed you had to do. If so, it might be that the step I'm doing is the one you want
In a nutshell though, I believe we open up the embedded raster object AIRasterizeSuite::Rasterize() creates and we convert that into a stream of pixels for output to PNG. I think that's what you want to know how to do? If so, the code I have is a little ugly, but maybe I get permission from my boss to share it. I'd explain the gist of it but honestly it's not my area of expertise -- I'm the vector guy, not the raster guy The fellow in the adjacent cubicle is the guy who wrote that stuff and he lives & breathes raster stuff!
Copy link to clipboard
Copied
Maybe you're skipping a step. Are you rasterizing other kinds of art straight to disk using the AIImageOptSuite? I've never used that suite, so maybe you're doing skipping a step I assumed you had to do. If so, it might be that the step I'm doing is the one you want
You are totally right. This is exactly what I do. For any kind of AIArtHandle, AllImageOptSuite is used.
Here it is this method (still to be imporved):
AIErr
AIArtHandleModifier::RasterizeArtToPNG(std::string path, const AIArtHandle &art, const AIRealRect& crop)
{
AIErr result =kNoErr;
AIDataFilter* dstFilter = 0;
AIDataFilter* filter = 0;
ai::UnicodeString file(path.c_str());
ai::FilePath fileP(file);
try
{
AIRealRect bounds;
sAIArt->GetArtBounds(art, &bounds);
AIReal width = bounds.right - bounds.left;
AIReal height = bounds.top - bounds.bottom;
if(width == 0 ||height == 0)
return kBadParameterErr;
result = sAIDataFilter->NewFileDataFilter(fileP, "write", 'prw', 'PNGf', &filter);
aisdk::check_ai_error(result);
result = sAIDataFilter->LinkDataFilter(dstFilter, filter);
aisdk::check_ai_error(result);
dstFilter = filter;
AIImageOptPNGParams2 params;
params.versionOneSuiteParams.interlaced = ConfigurationManager::GetInterlacedProperty();
params.versionOneSuiteParams.numberOfColors = ConfigurationManager::GetNumberOfColors();
params.versionOneSuiteParams.transparentIndex = ConfigurationManager::GetTransparentIndex();
params.versionOneSuiteParams.resolution = ConfigurationManager::GetResolution();
params.versionOneSuiteParams.outAlpha = ConfigurationManager::GetOutAlpha();
params.versionOneSuiteParams.outWidth = (ASInt32)width;
params.versionOneSuiteParams.outHeight = (ASInt32)height;
//We assume that the basic resolution of illustrator is 72 dpi
AIReal resolutionRatio = ConfigurationManager::GetResolution() / 72;
if(resolutionRatio == 0)
return kBadParameterErr;
AIReal minDim = min(width,height) * resolutionRatio;
AIReal maxDim = max(width,height) * resolutionRatio;
AIReal ratio = 1;
if(minDim < ConfigurationManager::minRasterizationDimension)
{
ratio = ConfigurationManager::minRasterizationDimension / minDim;
minDim *= ratio;
maxDim *= ratio;
}
if(maxDim > ConfigurationManager::maxRasterizationDimension)
{
ratio *= ConfigurationManager::maxRasterizationDimension / maxDim;
}
//Here we tune the resolution parameter to comply to minRasterizationDimension and
//maxRasterizationDimension constraints
//We assume that the basic resolution of illustrator is 72 dpi
params.versionOneSuiteParams.resolution *= ratio;
params.antialias = ConfigurationManager::GetAntialias();
/* A cropping box for the art. If empty or degenerate, do not crop. */
params.cropBox = crop;
params.backgroundIsTransparent = ConfigurationManager::GetBackgroundIsTransparentProperty();
/* When backgroundIsTransparent is false, rasterize against this matte color. */
/*params.matteColor.red = 1.0f;
params.matteColor.green = 1.0f;
params.matteColor.blue = 1.0f; */
result = sAIImageOpt->MakePNG24 (art, dstFilter, params, MyRasterizeProgressProc);
aisdk::check_ai_error(result);
if (dstFilter)
{
result = sAIDataFilter->UnlinkDataFilter (dstFilter, &dstFilter);
aisdk::check_ai_error(result);
}
}
catch(ai::Error& ex)
{
result = ex;
}
return result;
}
So the only thing, I have to do is to pass the AIArtHandle as parameter.
May be this is too generic, and I would have write a method to handle embedded raster. I will fixed this later.
I get an AIArtHandle ('AIArtHandle *raster' is the parameter name) which represents a raster object on the artboard. We then crack that open using AIRasterSuite::GetRasterInfo()
the same for me. and use GetRasterTile.......
I think that's what you want to know how to do? If so, the code I have is a little ugly, but maybe I get permission from my boss to share it
Excatly. This would be great.
Thanks for your help
Regards, Thomas.
Copy link to clipboard
Copied
I asked, but he's leary about sharing code unfortunately I can, however, explain what we're doing. Hopefully you understand raster mechanics more than me!
We have a function that basically pulls out the raw pixel data from the raster. The first step is to use AIRasterSuite::GetRasterInfo() on the raster artwork; this will fill an AIRasterRecord struct. Then you have to populate parts of an AITile and AISlice struct and request a 'result' AISlice. From looking at our code, it appears you can setup the AITile & request AISlice to get your data as one nice stream of pixel data. I'd look at the documentation in AIRaster, they have a really large block that would probably be a better way to understand this than my fumbling attempt to figure out what our code is doing.
The pseudocode thoug, looks something like this:
AIRasterRecord info;
sRaster->GetRasterInfo(handle, &info);
AITile tile;
// setup tile, including allocating space in data member for pixel data
AISlice request, outputSlice;
// setup request;
sRaster->GetRasterTile(handle, &request, &tile, &outputSlice);
// grab data from tile.data
At this point, you should have what I *think* is basically raw data of either RGB32 or ARGB32 depending on what you reuqested. I'd make a simple image (maybe half red, half blue?) and try embedding that and exporting it. That should make it easier to look at the debugging output and figure out if you're doing the right thing.
Sorry I can't share the code If you're still having trouble with later maybe I can try again asking my boss. Definitely read the AIRaster.h header documentation though, it looked pretty decent.
Copy link to clipboard
Copied
I will keep on looking this way, and let you know if I find the solution.
I will send you the code, so you could compare!
Anyway, many thanks for your help.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now