I use ReportingService.Render to get a stream of my report. I use TIFF format
and then I save it to a file.
According to this page
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rsprog/htm/rsp_prog_soapapi_dev_9xip.asp
you can determine the color depth of the report image if you use the TIFF
format.
My code is like this:
rs.Render(ReportName, "IMAGE", Nothing,
"<DeviceInfo><OutputFormat>TIFF</OutputFormat><DpiX>300</DpiX><DpiY>300</DpiY><ColorDepth>8</ColorDepth></DeviceInfo>", _
tmpParams, Nothing, Nothing, Nothing, Nothing, Nothing,
Nothing, Nothing)
My tif image is always 24 bit, no matter what I put in ColorDepth (higher or
lower).
Do you know how to fix it, or do you know a quick way to change the pixel
format of a file?
ThanksAmiram,
I don't have a KB article or anything, but MSFT staff have reported that
this is a known bug. Unfortunately, it did not get fixed in SP2, and last I
heard it did not make the cut for RS 2005 either.
I wrote code to loop over the pixels and convert the color depth to
monochrome, but it was too slow. It took about 3 seconds for a 600 x 800
TIFF, which was too long to do synchronously while the user waited. If you
want a color depth that does not require a palette, you can convert it very
quickly in code. However, I have failed to find any way to convert to
monochrome (with palette) without looping over the pixels. Because our
requirements allowed it, we ended up saving the 24 bpp TIFF files to disk and
using a utility to batch convert them once every few minutes.
HTH,
Ted
"Amiram Korach" wrote:
> My tif image is always 24 bit, no matter what I put in ColorDepth (higher or
> lower).
> Do you know how to fix it, or do you know a quick way to change the pixel
> format of a file?|||Thanks a lot.
I don't care to wait three seconds, because all process is in another
thread. Batch is too difficult for me, since I need to install it in each
client machine. Can you show some code for looping over the pixels? My tiff
file usually contains some frames.
Thanks
"Ted K" wrote:
> Amiram,
> I don't have a KB article or anything, but MSFT staff have reported that
> this is a known bug. Unfortunately, it did not get fixed in SP2, and last I
> heard it did not make the cut for RS 2005 either.
> I wrote code to loop over the pixels and convert the color depth to
> monochrome, but it was too slow. It took about 3 seconds for a 600 x 800
> TIFF, which was too long to do synchronously while the user waited. If you
> want a color depth that does not require a palette, you can convert it very
> quickly in code. However, I have failed to find any way to convert to
> monochrome (with palette) without looping over the pixels. Because our
> requirements allowed it, we ended up saving the 24 bpp TIFF files to disk and
> using a utility to batch convert them once every few minutes.
> HTH,
> Ted
> "Amiram Korach" wrote:
> > My tif image is always 24 bit, no matter what I put in ColorDepth (higher or
> > lower).
> >
> > Do you know how to fix it, or do you know a quick way to change the pixel
> > format of a file?
>|||Amiram,
Here's a snippet that does all the heavy lifting of switching frames,
looping over pixels, and saving the image. Note that, in order to try to
speed this up as much as possile, this uses unsafe code. If you prefer safe
code to performance, you can get rid of the bit twiddling and let .NET set
each bit.
If you have more questions, you can email me. Just take out the "nospam"
parts of my email address.
abyteResult = m_oRS.Render(a_sReportPath, sFormat, sHistoryID, sDevInfo,
a_aoParams, oCredentials, sShowHideToggle,
out sEncoding, out sMimeType, out aoReportHistoryParameters, out
aoWarnings, out sStreamIDs);
// Create a memory stream from our byte array
oStream = new MemoryStream(abyteResult);
// Set the position to the beginning of the stream
oStream.Seek(0, SeekOrigin.Begin);
// Load the stream into an image
Bitmap oImage = new Bitmap(oStream);
// Get number of images (frames)
oFD = new FrameDimension(oImage.FrameDimensionsList[0]);
nFrames = oImage.GetFrameCount(oFD);
/// Write to file using a specific format
// Get an ImageCodecInfo object that represents the TIFF codec.
oImageCodecInfo = oGetCodecInfo("image/tiff");
oEncoderParameters = new EncoderParameters(2);
oEncoder = Encoder.Compression;
oEncoderParameter = new EncoderParameter(oEncoder,
(long)EncoderValue.CompressionNone);
oEncoderParameters.Param[0] = oEncoderParameter;
oEncoder = Encoder.SaveFlag;
oEncoderParameter = new EncoderParameter(oEncoder,
(long)EncoderValue.MultiFrame);
oEncoderParameters.Param[1] = oEncoderParameter;
// COPY IMAGE AND MAKE IT BLACK AND WHITE
Rectangle oRect = new Rectangle(0, 0, oImage.Width, oImage.Height);
PixelFormat oFormat = PixelFormat.Format1bppIndexed;
Bitmap oNew = new Bitmap(oImage.Width, oImage.Height, oFormat);
BitmapData bmd=oNew.LockBits(oRect, ImageLockMode.ReadWrite, oFormat);
for(int y=0;y<oImage.Height;y++) {
for(int x=0;x<oImage.Width;x++) {
if(oImage.GetPixel(x,y).GetBrightness()>0.5f)
this.SetIndexedPixel(x,y,bmd,true);
}
}
oNew.UnlockBits(bmd);
// Save the file using the TIFF codec and the configured parameters
oNew.Save(a_sDestinationPath, oImageCodecInfo, oEncoderParameters);
for (int i=1; i < nFrames; i++) {
Bitmap oCopy;
// Move to the next frame
oImage.SelectActiveFrame(oFD, i);
// oEncoderParameters = new EncoderParameters(3);
oEncoder = Encoder.SaveFlag;
oEncoderParameter = new EncoderParameter(oEncoder,
(long)EncoderValue.FrameDimensionPage);
oEncoderParameters.Param[1] = oEncoderParameter;
oRect = new Rectangle(0, 0, oImage.Width, oImage.Height);
oCopy = new Bitmap(oImage.Width, oImage.Height, oFormat);
bmd=oCopy.LockBits(oRect, ImageLockMode.ReadWrite, oFormat);
for(int y=0;y<oImage.Height;y++) {
for(int x=0;x<oImage.Width;x++) {
if(oImage.GetPixel(x,y).GetBrightness()>0.5f)
this.SetIndexedPixel(x,y,bmd,true);
}
}
oCopy.UnlockBits(bmd);
oNew.SaveAdd(oCopy, oEncoderParameters);
}
oEncoderParameters = new EncoderParameters(1);
oEncoder = Encoder.SaveFlag;
oEncoderParameter = new EncoderParameter(oEncoder, (long)EncoderValue.Flush);
oEncoderParameters.Param[0] = oEncoderParameter;
oNew.SaveAdd(oEncoderParameters);
...
private static ImageCodecInfo oGetCodecInfo(String mimeType) {
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for(j = 0; j < encoders.Length; ++j) {
if(encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
protected unsafe void SetIndexedPixel(int x,int y,BitmapData bmd, bool
pixel) {
byte* p=(byte*)bmd.Scan0.ToPointer();
int index=y*bmd.Stride+(x>>3);
byte mask=(byte)(0x80>>(x&0x7));
if(pixel)
p[index]|=mask;
else
p[index]&=(byte)(mask^0xff);
}
Regards,
Ted
"Amiram Korach" wrote:
> Thanks a lot.
> I don't care to wait three seconds, because all process is in another
> thread. Batch is too difficult for me, since I need to install it in each
> client machine. Can you show some code for looping over the pixels? My tiff
> file usually contains some frames.
> Thanks
> "Ted K" wrote:
> > Amiram,
> > I don't have a KB article or anything, but MSFT staff have reported that
> > this is a known bug. Unfortunately, it did not get fixed in SP2, and last I
> > heard it did not make the cut for RS 2005 either.
> >
> > I wrote code to loop over the pixels and convert the color depth to
> > monochrome, but it was too slow. It took about 3 seconds for a 600 x 800
> > TIFF, which was too long to do synchronously while the user waited. If you
> > want a color depth that does not require a palette, you can convert it very
> > quickly in code. However, I have failed to find any way to convert to
> > monochrome (with palette) without looping over the pixels. Because our
> > requirements allowed it, we ended up saving the 24 bpp TIFF files to disk and
> > using a utility to batch convert them once every few minutes.
> >
> > HTH,
> > Ted
> >
> > "Amiram Korach" wrote:
> >
> > > My tif image is always 24 bit, no matter what I put in ColorDepth (higher or
> > > lower).
> > >
> > > Do you know how to fix it, or do you know a quick way to change the pixel
> > > format of a file?
> >
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment