Источник:
http://blog.equalized.be/2011/01/dyn...os-from-batch/
==============
Hi,
As all of you know the
Image class in Dynamics Ax 4.0 and 2009 can only run on client. This poses a problem when you want to print for example invoices with your company logo on it. Having this found out I went to look for an alternative!
I’ve added this code to the top of the PDFViewer class in the writeBitmap(OutputBitmapField _field, OuputSection _section) method
X++:
if( isRunningOnServer() &&
_field.name() == #FieldLogo)
{
this.BLOGWriteBitmapOnServer(_field,_section);
super(_field, _section);
return;
}
For the method BLOGWriteBitmapOnServer(OutputBitmapField _field, OuputSection _section) I have copied everything from the writeBitmap and started by replacing the Image object with a System.Drawing.Image object, you can make a company parameter for this file path.
X++:
img = System.Drawing.Image::FromFile(imgStr);
After compiling there are a few errors witch I’ve corrected and ended up with this code.
X++:
public void BLOGWriteBitmapOnServer(OutputBitmapField _field, OuputSection _section)
{
#File
BinData bin = new BinData();
//Image img;
container data, imgInfoData;
str s;
real x1,x2, y1,y2;
Struct br;
int imageObjectNo = 0;
int newwidth, newheight;
real pdfPreviewScale = 0.8;
boolean generateXImage = false;
container c;
str fn;
FileIOPermission writePermission;
FileIOPermission readPermission;
boolean grayScale = false;
System.Drawing.Image img;
str imgStr;
int widthTemp, heightTemp;
CompanyInfo companyInfo = companyInfo::find();
;
new InteropPermission(InteropKind::ClrInterop).assert();
imgStr = companyInfo.BLOGCompanyLogoFile;
br = this.boundingRectTwips(currentPage, _section, _field);
x1 = br.value('x1'); y1 = br.value('y1');
x2 = br.value('x2'); y2 = br.value('y2');
if (_field.type() == 10) // resourceId, DB_RESId
{
//img = new Image(_field.resourceId());
img = System.Drawing.Image::FromFile(imgStr);
if (resourceIdImageMap.exists(_field.resourceId()))
imageObjectNo = resourceIdImageMap.lookup(_field.resourceId());
else
{
imageObjectNo = this.nextObjectNo();
resourceIdImageMap.insert(_field.resourceId(), imageObjectNo);
generateXImage = true;
}
if (debugLevel >= 1)
info ('Image in resource ' + int2str(_field.resourceId()));
}
else if (_field.type() == 7) // queue
{
c = _field.value();
if (c)
{
//img = new Image(c);
img = System.Drawing.Image::FromFile(imgStr);
imageObjectNo = this.nextObjectNo();
}
generateXImage = true;
if (debugLevel >= 1)
{
if (img)
info ('Image in container');
else
info ('No image in container');
}
}
else // string containing filename
{
//img = new Image(_field.imageFileName());
img = System.Drawing.Image::FromFile(imgStr);
if (stringImageMap.exists(_field.imageFileName()))
imageObjectNo = stringImageMap.lookup(_field.imageFileName());
else
{
imageObjectNo = this.nextObjectNo();
stringImageMap.insert(_field.imageFileName(), imageObjectNo);
generateXImage = true;
}
if (debugLevel >= 1)
info ('File is ' + _field.imageFileName());
}
if (img)
{
if (generateXImage)
{
fn = System.IO.Path::GetTempFileName();
widthTemp = img.get_Width();
heightTemp = img.get_Height();
img.Save(fn);
// revert previous assertion
CodeAccessPermission::revertAssert();
// assert read permissions
readPermission = new FileIOPermission(fn, #io_read);
readPermission.assert();
// BP deviation documented (note that the file io assert IS included above)
bin.loadFile(fn);
data = bin.getData();
// Get rid of the temporary file.
//WinAPIServer::deleteFile(fn);
CodeAccessPermission::revertAssert();
new InteropPermission(InteropKind::ClrInterop).assert();
System.IO.File::Delete(fn);
if (bitmapEncode85)
s = bin.ascii85Encode();
else
s = BinData::dataToString(data);
objectOffsetMap.insert(imageObjectNo, binBuffer.size());
this.appendTextToBuffer(int2str(imageObjectNo) + ' 0 obj <<\n');
if (grayScale)
{
this.appendTextToBuffer(' /Type/XObject /Subtype/Image /ColorSpace /DeviceGray\n');
}
else
{
this.appendTextToBuffer(' /Type/XObject /Subtype/Image /ColorSpace /DeviceRGB\n');
}
this.appendTextToBuffer(' /Name /I' + int2str(imageObjectNo) + ' /BitsPerComponent 8\n');
if (!bitmapEncode85)
{
this.appendTextToBuffer(' /Filter [/ASCIIHexDecode/DCTDecode] /DecodeParms[null<<>>]\n');
this.appendTextToBuffer(strfmt(' /Length %1\n', strlen(s)+1)); // Allow for end of data marker
}
else
{
this.appendTextToBuffer(' /Filter [/ASCII85Decode/DCTDecode] /DecodeParms[null<<>>]\n');
this.appendTextToBuffer(strfmt(' /Length %1\n', strlen(s)));
}
// Specify dimensions via newwidth/newheight.
this.appendTextToBuffer(strfmt(' /Width %1 /Height %2\n', widthTemp, heightTemp));
this.appendTextToBuffer('>>\nstream\n');
this.appendTextToBuffer(s);
if (!bitmapEncode85)
this.appendTextToBuffer('>'); // End of Data marker
this.appendTextToBuffer('\nendstream\nendobj\n');
}
// Have to put imageObjectNo or it will be only on page #1
imagesOnPage.add(imageObjectNo);
// Generate the object that draws the image...
s = 'q\n';
s += this.drawFieldFrame(_field, x1, y1, x2, y2);
// Provide a scaling factor bringing the image size up to the size requested by the report
// Also, provide x,y pos)
if (_field.resize())
s += ' ' + this.real2str(x2-x1) + ' 0 0 ' + this.real2str(y2-y1) + ' ' + this.real2str(x1) + ' ' + this.real2str(y1) + ' cm\n';
else
{
//We should resize the bitmap according to the area given in PDF page otherwise there will be out of area drawing
//The PDF bitmap drawing has wrong scaling from what we see in the preview so we should also scale it by PDFPreviewScale
newwidth = min(abs(x2-x1)/pdfPreviewScale, widthTemp);
newheight = min(abs(y2-y1)/pdfPreviewScale, heightTemp);
x1 += this.twips(this.borderWidth(_field.borderWidth(), _field.lineLeft()));
y1 += this.twips(this.borderWidth(_field.borderWidth(), _field.lineRight()));
x2 -= this.twips(this.borderWidth(_field.borderWidth(), _field.lineTop()));
y2 -= this.twips(this.borderWidth(_field.borderWidth(), _field.lineBottom()));
if (_field.alignment() == Alignment::Center)
{
x1 = (x1 + x2 - newwidth) / 2;
y1 = (y1 + y2 - newheight) / 2;
}
else if (_field.alignment() == Alignment::Right)
{
x1 = x2 - newwidth;
y1 = y2 - newheight;
}
else // left
{
y1 = y2 - newheight;
}
s += ' ' + this.real2str(newwidth) + ' 0 0 ' + this.real2str(newheight) + ' ' + this.real2str(x1) + ' ' + this.real2str(y1) + ' cm\n';
}
s += ' /I' + int2str(imageObjectNo) + ' Do\n';
s += 'Q\n';
this.appendTextToPage(s);
}
CodeAccessPermission::revertAssert();
}
This could probably been done much cleaner, but it does the job.
Источник:
http://blog.equalized.be/2011/01/dyn...os-from-batch/