Thursday, March 29, 2012

Draw Bitmap from Points in report

Hi, i have a database field that has a drawing stored as points, for example....

(x1,y1)(x2,x2)(x1,y1)(x2,x2)(x1,y1)(x2,x2)(x1,y1)(x2,x2)(x1,y1)(x2,x2)(x1,y1)(x2,x2)(x1,y1)(x2,x2)

In my VB.NET application, i can take those points and recreate the image. I need to do the same in reporting services... i am trying to replace a legacy ACCESS report, that had the drawing object.

How can i recreate the image in reporting services? is there an easy way to do so? i believe i tried to create a class and tried to reference it and call the function to return the data as an image, but i got a system.drawing not found error...

There are at least two options:

1. use the built-in charts with chart type = scatter. Note: the scatter chart must have a category grouping based on a unique value (e.g. data point id in your case). I attached a small sample report to the bottom of this posting to show the idea.

2. or draw the image yourself and use it in Reporting Services. However, make sure to follow these steps:

2.1. Design and implement a custom assembly to generate images.
The custom assembly must retrieve the data on its own, take care of grouping/sorting the data, and generating the chart image.
Note: The custom assembly has to return the image as byte[]. It cannot return it as a System.Drawing.Image. You can often convert a System.Drawing.Image object with code similar to the following.
System.IO.MemoryStream renderedImage = new MemoryStream();
myChart.Save(renderedImage);
renderedImage.Position = 0;
return renderedImage.ToArray();

2.2. Add an image to the report.
Set the image type to Database. If the generated image is a bitmap in the PNG image format, set the image mimetype property to “image/png.” For the image value property, use an expression like the following.
=MyCustomAssembly.GenerateChart()

2.3. View the report in Report Designer Preview view to verify that the report is working correctly.
Note: In a default configuration, custom assemblies run in FullTrust in Report Designer preview. Hence, operations that require certain code access security permissions (such as file input/output, data provide access, etc.) are automatically granted these permissions in Fulltrust.

2.4. Deploy the custom assembly on a report server.
Make sure that the security policy configuration of the report server grants sufficient permissions to your custom assembly at runtime; otherwise the image generation will fail. For more information, see Understanding Code Access Security in Reporting Services (http://msdn2.microsoft.com/en-us/library/ms155108.aspx) in SQL Server 2005 Books Online.

-- Robert

=========================================

<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<DataSources>
<DataSource Name="AdventureWorks">
<DataSourceReference>AdventureWorks</DataSourceReference>
<rd:DataSourceID>67061ec4-b72e-4a04-a7f3-714536211b9c</rd:DataSourceID>
</DataSource>
</DataSources>
<BottomMargin>1in</BottomMargin>
<RightMargin>1in</RightMargin>
<rd:DrawGrid>true</rd:DrawGrid>
<InteractiveWidth>8.5in</InteractiveWidth>
<rd:SnapToGrid>true</rd:SnapToGrid>
<Body>
<ReportItems>
<Chart Name="chart1">
<Legend>
<Style>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
</Style>
<Position>RightCenter</Position>
</Legend>
<Subtype>Line</Subtype>
<Title />
<Height>2in</Height>
<CategoryAxis>
<Axis>
<Title />
<Style>
<Format>MMM dd</Format>
</Style>
<MajorGridLines>
<Style>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
</Style>
</MajorGridLines>
<MinorGridLines>
<Style>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
</Style>
</MinorGridLines>
<MajorTickMarks>Outside</MajorTickMarks>
<Visible>true</Visible>
<Scalar>true</Scalar>
</Axis>
</CategoryAxis>
<PointWidth>0</PointWidth>
<Left>0.125in</Left>
<ThreeDProperties>
<Rotation>30</Rotation>
<Inclination>30</Inclination>
<Shading>Simple</Shading>
<WallThickness>50</WallThickness>
</ThreeDProperties>
<DataSetName>DataSet1</DataSetName>
<SeriesGroupings>
<SeriesGrouping>
<StaticSeries>
<StaticMember>
<Label>Value1</Label>
</StaticMember>
</StaticSeries>
</SeriesGrouping>
</SeriesGroupings>
<Top>0.125in</Top>
<PlotArea>
<Style>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
<BackgroundColor>WhiteSmoke</BackgroundColor>
<BackgroundGradientEndColor>White</BackgroundGradientEndColor>
<BackgroundGradientType>TopBottom</BackgroundGradientType>
</Style>
</PlotArea>
<ValueAxis>
<Axis>
<Title />
<MajorGridLines>
<ShowGridLines>true</ShowGridLines>
<Style>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
</Style>
</MajorGridLines>
<MinorGridLines>
<Style>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
</Style>
</MinorGridLines>
<MajorTickMarks>Outside</MajorTickMarks>
<Min>0</Min>
<MajorInterval>5</MajorInterval>
<Margin>true</Margin>
<Visible>true</Visible>
<Scalar>true</Scalar>
</Axis>
</ValueAxis>
<Type>Scatter</Type>
<Width>3.5in</Width>
<CategoryGroupings>
<CategoryGrouping>
<DynamicCategories>
<Grouping Name="chart1_CategoryGroup1">
<GroupExpressions>
<GroupExpression>=Fields!MeasurementId.Value</GroupExpression>
</GroupExpressions>
</Grouping>
<Sorting>
<SortBy>
<SortExpression>=CDate(Fields!TimeStamp.Value)</SortExpression>
<Direction>Ascending</Direction>
</SortBy>
</Sorting>
<Label>=Fields!MeasurementId.Value</Label>
</DynamicCategories>
</CategoryGrouping>
</CategoryGroupings>
<Palette>EarthTones</Palette>
<ChartData>
<ChartSeries>
<DataPoints>
<DataPoint>
<DataValues>
<DataValue>
<Value>=CDate(Fields!TimeStamp.Value)</Value>
</DataValue>
<DataValue>
<Value>=Fields!Value.Value</Value>
</DataValue>
</DataValues>
<DataLabel />
<Style>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
<BorderWidth>
<Default>4.5pt</Default>
</BorderWidth>
</Style>
<Marker>
<Size>6pt</Size>
</Marker>
</DataPoint>
</DataPoints>
</ChartSeries>
</ChartData>
<Style>
<BackgroundColor>White</BackgroundColor>
</Style>
</Chart>
</ReportItems>
<Height>2.25in</Height>
</Body>
<rd:ReportID>a068be44-d5ee-4243-91ed-445f05622d2c</rd:ReportID>
<LeftMargin>1in</LeftMargin>
<DataSets>
<DataSet Name="DataSet1">
<Query>
<rd:UseGenericDesigner>true</rd:UseGenericDesigner>
<CommandText>select 1 as MeasurementId, '07/16/2006' as TimeStamp, 10 as Value union
select 2 as MeasurementId, '07/17/2006' as TimeStamp, 10 as Value union
select 3 as MeasurementId, '07/17/2006' as TimeStamp, 8 as Value union
select 4 as MeasurementId, '07/18/2006' as TimeStamp, 8 as Value union
select 5 as MeasurementId, '07/19/2006' as TimeStamp, 10 as Value union
select 6 as MeasurementId, '07/19/2006' as TimeStamp, 12 as Value union
select 7 as MeasurementId, '07/20/2006' as TimeStamp, 12 as Value union
select 8 as MeasurementId, '07/21/2006' as TimeStamp, 12 as Value union
select 9 as MeasurementId, '07/21/2006' as TimeStamp, 9 as Value union
select 10 as MeasurementId, '07/22/2006' as TimeStamp, 9 as Value</CommandText>
<DataSourceName>AdventureWorks</DataSourceName>
</Query>
<Fields>
<Field Name="MeasurementId">
<rd:TypeName>System.Int32</rd:TypeName>
<DataField>MeasurementId</DataField>
</Field>
<Field Name="TimeStamp">
<rd:TypeName>System.String</rd:TypeName>
<DataField>TimeStamp</DataField>
</Field>
<Field Name="Value">
<rd:TypeName>System.Int32</rd:TypeName>
<DataField>Value</DataField>
</Field>
</Fields>
</DataSet>
</DataSets>
<Author>Robert M. Bruckner, Microsoft</Author>
<Width>3.75in</Width>
<InteractiveHeight>11in</InteractiveHeight>
<Language>en-US</Language>
<TopMargin>1in</TopMargin>
</Report>

|||

Thanks for posting a reply ill try it first thing in the morning....

The drawing is collected on a handheld, its actually a signature (but it can be a drawing as well, so lots of points....), the coordinates of the drawing are saved in an xml file along with other data, and is then inserted into the database when the device is synced....

ill try the chart way first, and then the custom assembly again. when i tried it last time it was giving me the bitmap not defined error, i dont remember if i was returning the data as an image or as a byte... :) ill give it a try and post back here so that someone else can also make use of your help!

thank you.

|||omg...... thats for the reply and the hints, i doublechecked everything in your 2nd suggestion with what i had already done, the first one wasnt feasible... and after checking all your suggestions i realised that it had been working all this time!!!., it just doesnt work in DEBUG mode... :( when i ran the application itself outside of VS, it ran with no problems!!!!|||Make sure you have copied your assembly to the C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies folder.

No comments:

Post a Comment