I'm having difficulties rendering a SSRS serverreport and printing it from code.
Although rendering succeeds and the report is printed, the results in quality in the graphics are poor. The report itself has a high res 6kx1k GIF image for the logo.
I've made image below to illustrate the difference between rendering using EMF versus PDF:
As you can see the font look great (no pixallation) and when rendering in PDF logo look good. However the EMF version has poor quality as you can see on the edges in the logo.
Anyone came across this and solved it?
I'm running SQL Server 2008R2 SP2 (10.50.4000)
Code to render the report using EMF
public List<byte[]> Render()
{
// Setting credentials and reporting services uri
ReportExecutionService reportService = new ReportExecutionService
{
Credentials = _credentials,
Url = Settings.Default.ReportingService
};
// Prepare report parameter.
ExecutionHeader execHeader = new ExecutionHeader();
reportService.ExecutionHeaderValue = execHeader;
reportService.LoadReport(_report, null);
reportService.SetExecutionParameters(_parameters.ToArray(), "en-us");
// Render
bool startup = true;
List<byte[]> streams = new List<byte[]>();
int numberOfPages = 0;
byte[] result = null;
while (startup || result.Length > 0)
{
startup = false;
string devInfo = String.Format(#"<DeviceInfo><OutputFormat>EMF</OutputFormat><PrintDpiX>150</PrintDpiX><PrintDpiY>150</PrintDpiY><StartPage>{0}</StartPage></DeviceInfo>", numberOfPages + 1);
string encoding, mimeType, extension;
string[] streamIDs = null;
Warning[] warnings = null;
result = reportService.Render("IMAGE", devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
if (result.Length > 0)
{
streams.Add(result);
}
numberOfPages++;
}
return streams;
}
Here's the printdocument implementation
public class PrintReport : PrintDocument
{
private int _currentPage;
private List<byte[]> _pages;
public PrintReport()
{
}
public List<byte[]> Pages
{
get { return _pages; }
set { _pages = value; }
}
protected override void OnBeginPrint(PrintEventArgs e)
{
base.OnBeginPrint(e);
_currentPage = 0;
}
protected override void OnPrintPage(PrintPageEventArgs e)
{
base.OnPrintPage(e);
Stream pageToPrint = new MemoryStream(_pages[_currentPage]);
pageToPrint.Position = 0;
// Load each page into a Metafile to draw it.
using (Metafile pageMetaFile = new Metafile(pageToPrint))
{
Rectangle adjustedRect = new Rectangle(
e.PageBounds.Left - (int)e.PageSettings.HardMarginX,
e.PageBounds.Top - (int)e.PageSettings.HardMarginY,
e.PageBounds.Width,
e.PageBounds.Height);
// Draw a white background for the report
e.Graphics.FillRectangle(Brushes.White, adjustedRect);
// Draw the report content
e.Graphics.DrawImage(pageMetaFile, adjustedRect);
// Prepare for next page. Make sure we haven't hit the end.
_currentPage++;
e.HasMorePages = _currentPage < _pages.Count;
}
}
protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
{
e.PageSettings = (PageSettings)PrinterSettings.DefaultPageSettings.Clone();
}
}
Try replacing "150" with the desired dpi in the snippet below copied from devInfo, it should help. Changing it to "300" solved my similar issue.
<PrintDpiX>150</PrintDpiX><PrintDpiY>150</PrintDpiY>
Note that it can be frustrating to change this in your reports as the report viewer rendering engine will still show with 150 dpi when previewing your reports, so you will need to test your layouts using your code for testing after each update to the rdl.
Related
I have added a WriteableBitmapExtension via NuGet to my Windows Phone 8.1 WinRT app. I have functions to capture an image from camera and save it to picture library. I tried rotate captured image before save and I found solution here
WriteableBitmap crashes program with no message?. Everything works fine on emulator but when I run my app on Nokia Lumia 630 it crashes few seconds after taking a photo without debbuger message. Can anyone help me with this issue? Here is my code of taking photo:
public WriteableBitmap Image
{
get
{
return this.image;
}
set
{
this.image = value;
this.RaisePropertyChanged(() => this.Image);
}
}
private async void TakePhoto()
{
using (var stream = new InMemoryRandomAccessStream())
{
var imgEncodingProperties = ImageEncodingProperties.CreateJpeg();
var img = BitmapFactory.New(640, 480);
await this.MediaCapture.CapturePhotoToStreamAsync(imgEncodingProperties, stream);
stream.Seek(0);
img.SetSource(stream);
WriteableBitmapExtensions.DrawLine(img, 10, 10, 300, 300, Colors.Black);
this.Image = img.Rotate(90);
this.TurnOffCaptureMode();
}
}
private void TurnOffCaptureMode()
{
this.MediaCapture.StopPreviewAsync();
this.IsInCaptureMode = false;
}
Alternate solution is here.
1 Open file Picket use build in camera to take picture.
var openPicker = new FileOpenPicker();
openPicker.ContinuationData["Action"] = "SendPicture";
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".png");
openPicker.PickSingleFileAndContinue();
***2. In app.xaml.cs you will get captured image. as below.***
public void Continue(IContinuationActivatedEventArgs args)
{
if(args.Kind == ActivationKind.PickFileContinuation)
{
var openPickerContinuationArgs = args as FileOpenPickerContinuationEventArgs;
// Recover the "Action" info we stored in ContinuationData
string action = (string) openPickerContinuationArgs.ContinuationData["Action"];
if(openPickerContinuationArgs.Files.Count > 0)
{
// TODO: Get the files here
}
else
{
// TODO: Write code here to handle picker cancellation.
}
}
}
I'm really confusing ! I get this error randomly, Sometime the code worked (yesterday code went okay) but sometime not (today it returned "InvalidRequest" error).
I put this code in every page of my app
public MainPage()
{
InitializeComponent();
DataContext = App.MyModel;
LoadAd();
}
void LoadAd()
{
AdView av = new AdView()
{
AdUnitID = "ca-app-pub-...",
Format = AdFormats.Banner,
VerticalAlignment = System.Windows.VerticalAlignment.Top,
HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
};
av.FailedToReceiveAd += av_FailedToReceiveAd;
LayoutRoot.Children.Add(av);
AdRequest ar = new AdRequest();
ar.ForceTesting = true;
av.LoadAd(ar);
}
void av_FailedToReceiveAd(object sender, AdErrorEventArgs e)
{
Debug.WriteLine(e.ErrorCode.ToString());
}
I have found out that this error is mostly due to incorrect ad unit ids.
Check your adid, and make sure that its correct and doesnt have any space
I have tried this code
public System.Drawing.Bitmap CaptureWebPage(string URL)
{
// create a hidden web browser, which will navigate to the page
System.Windows.Forms.WebBrowser web = new System.Windows.Forms.WebBrowser();
// we don't want scrollbars on our image
web.ScrollBarsEnabled = false;
// don't let any errors shine through
web.ScriptErrorsSuppressed = true;
// let's load up that page!
web.Navigate(URL);
// wait until the page is fully loaded
while (web.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
System.Threading.Thread.Sleep(1500); // allow time for page scripts to update
// the appearance of the page
// set the size of our web browser to be the same size as the page
int width = web.Document.Body.ScrollRectangle.Width;
int height = web.Document.Body.ScrollRectangle.Height;
web.Width = width;
web.Height = height;
// a bitmap that we will draw to
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
// draw the web browser to the bitmap
web.DrawToBitmap(bmp, new System.Drawing.Rectangle(0, 0, width, height));
return bmp; // return the bitmap for processing
}
protected void btnConvert_Click(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(CaptureWebPage(txtUrl.Text));
Response.ContentType = "image/jpeg";
bitmap.Save(Response.OutputStream, ImageFormat.Jpeg);
bitmap.Dispose();
bitmap.Dispose();
Response.End();
}
I am able to capture google.com,but not able to capture images of our web site since it contains form authentication so it redirects me to login page and login page is captured.Please help to pass through authentication.Can we use sessions,cookies or anything with the WebBrowser to valid it Or something.Please suggest.
Try on the intended page on your website :
System.Text.StringBuilder sb = new System.Text.StringBuilder();
System.IO.StringWriter sw = new System.IO.StringWriter(sb);
Page.RenderControl(new HtmlTextWriter(sw));
and then use the HTML in the string builder to render the page like the example below (Reference : Convert HTML string to image) :
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
class Program
{
static void Main(string[] args)
{
var source = #"
<!DOCTYPE html>
<html>
<body>
<p>An image from W3Schools:</p>
<img
src=""http://www.w3schools.com/images/w3schools_green.jpg""
alt=""W3Schools.com""
width=""104""
height=""142"">
</body>
</html>";
StartBrowser(source);
Console.ReadLine();
}
private static void StartBrowser(string source)
{
var th = new Thread(() =>
{
var webBrowser = new WebBrowser();
webBrowser.ScrollBarsEnabled = false;
webBrowser.DocumentCompleted +=
webBrowser_DocumentCompleted;
webBrowser.DocumentText = source;
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
static void
webBrowser_DocumentCompleted(
object sender,
WebBrowserDocumentCompletedEventArgs e)
{
var webBrowser = (WebBrowser)sender;
using (Bitmap bitmap =
new Bitmap(
webBrowser.Width,
webBrowser.Height))
{
webBrowser
.DrawToBitmap(
bitmap,
new System.Drawing
.Rectangle(0, 0, bitmap.Width, bitmap.Height));
bitmap.Save(#"filename.jpg",
System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
I was having a hard time loading training set from Ms Access database in to the main form that does the Face Recognition. I saved the training sets with their names and ID in to the database as a binary data with an OLE Object format.The method i used to change, save and read the data from the database and in to the training sets is
private static byte[] ConvertImageToBytes(Image InputImage)
{
using (Bitmap BmpImage = new Bitmap(InputImage))
{
using (MemoryStream MyStream = new MemoryStream())
{
BmpImage.Save(MyStream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] ImageAsBytes = MyStream.ToArray();
return ImageAsBytes;
}
}
}
The method that i use to store the converted byte data to the database is the following:
private void StoreData(byte[] ImageAsBytes,String NameStudent,String IDStudent)
{
if (DBConnection.State.Equals(ConnectionState.Closed))
DBConnection.Open();
try
{
//MessageBox.Show("Saving image at index : " + rowPosition);
using (OleDbCommand insert = new OleDbCommand(String.Format("Insert INTO
TrainingSet(rowPosition,StudentName,StudentID,StudentFace) values ('
{0}','{1}','{2}',#StudentFace)", rowPosition, NameStudent, IDStudent),
DBConnection))
{
OleDbParameter imageParameter = insert.Parameters.AddWithValue(#"StudentFace",
SqlDbType.Binary);
imageParameter.Value = ImageAsBytes;
imageParameter.Size = ImageAsBytes.Length;
int rowsAffected = insert.ExecuteNonQuery();
MessageBox.Show(String.Format("Data stored successfully in {0}
Row",rowsAffected));
}
rowPosition++;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
MessageBox.Show(ex.Message);
}
finally
{
RefreshDBConnection();
}
}
The method that i use to Read this binary data is as follows:
private Image ReadImageFromDB()
{
Image FetchedImg;
if (rowNumber >= 0)
{
byte[] FetchedImgBytes = (byte[])LocalDataTable.Rows[rowNumber]["StudentFace"];
MemoryStream stream = new MemoryStream(FetchedImgBytes);
FetchedImg = Image.FromStream(stream);
return FetchedImg;
}
else
{
MessageBox.Show("There are no images in the database yet.Please reconnect
or add some pictures.");
return null;
}
}
I have successfully saved the training sets/images as a binary data in to the database.The problem is when i load these training sets for Recognition.
// Declaring the variables=====trainingImages is where the training sets are
// loaded from the database NameLabels and IDLabels are text in the database
// and where name and Id of subject
//is saved.
List<Image<Gray,byte>> trainingImages = new List<Image<Gray,byte>>();
List<string> NameLables= new List<string>();
List<string> IDLables = new List<string>();
int ContTrain, NumNameLabels,NumIDLabels, t;
//The training sets from the database are loaded in to the facerecognizer code as
// follows
public FaceRecognizer()
{
InitializeComponent();
try
{
//Load previous trained and labels for each image from the database Here
RefreshDBConnection();
String[] NameLabels = (String[])LocalDataTable.Rows[rowNumber]["StudentName"];
NumNameLabels = Convert.ToInt16(NameLabels[0]);
String[] IDLabels = (String[])LocalDataTable.Rows[rowNumber]["StudentID"];
NumIDLabels = Convert.ToInt16(IDLabels[0]);
if (NumNameLabels == NumIDLabels)
{
ContTrain = NumNameLabels;
string LoadFaces;
// Converting the master image to a bitmap
Image imageFromDB;
Bitmap imageChangedToBitmap;
// Normalizing it to grayscale
Image<Gray, Byte> normalizedMasterImage;
for (int tf = 1; tf < NumNameLabels + 1; tf++)
{
imageFromDB = ReadImageFromDB();
//image loaded from the database is converted in to Bitmap and then
//convert the bitmap image in to Image<Gray,byte> for input to
//EigenObjectRecognizer(,,,)
imageChangedToBitmap = new Bitmap(imageFromDB);
normalizedMasterImage = new Image<Gray, Byte>(imageChangedToBitmap);
LoadFaces = String.Format("face{0}.bmp", tf);
trainingImages.Add(normalizedMasterImage);
//trainingImages.Add(new Image<Gray, byte>());
NameLables.Add(NameLabels[tf]);
IDLables.Add(IDLabels[tf]);
rowNumber = rowNumber + 1;
}
}
else
MessageBox.Show("There's a conflict between Name labels and id labels");
}
catch (Exception e)
{
MessageBox.Show("Nothing in the database, please add at least a
face.Train the database","Triained faces load",MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
I am only getting the message in the catch when the the form loads even if there are faces saved in the database. I have used EigenObjectRecognizer and i will post the code if necessary.
at the part of loading face, you did not save by face1, face2, face3 etc. So you can not load using;
LoadFaces = String.Format("face{0}.bmp", tf);
Per the Google Page Speed recommendations, I want to Specify image dimensions to "Optimize browser rendering."
Specifying a width and height for all
images allows for faster rendering by
eliminating the need for unnecessary
reflows and repaints.
I am investigating ways to traverse through the image files (PNG, JPEG) in my static content project and output a file with the path and filename of each image file as well as the height and width in pixels. I would then use that to help me construct the tags by using the src attribute data to lookup the values to use for the height and width attributes.
\images\logo.png,100,25
My first ideas was looking for an ANT task, since our static content build uses Ant for other purposes (like using YUI Compressor on JavaScript and CSS files). I am open to other ideas as well, including other methods to solve this problem. I would prefer to not have to manually do this work.
You could try this https://github.com/mattwildig/image-size-report-task, which I've made just for this question.
Here was what I implemented so far (needs testing and clean up). Basically, used Tutorial: Tasks using Properties, Filesets & Paths to get me started in an Ant task and How to get image height and width using java? to extract the image dimensions. I'm going to compare against matt's answer before I deploy.
The test build script from my project:
<project name="ImagesTask" basedir="." default="test">
<target name="init">
<taskdef name="images" classname="ImageInfoTask" classpath="..\dist\ImageTask.jar"/>
</target>
<target name="test" depends="init">
<images outputFile="data/images.xml">
<fileset dir="data" includes="images/**/*.jpg"/>
<fileset dir="data" includes="images/**/*.gif"/>
<fileset dir="data" includes="images/**/*.png"/>
</images>
</target>
</project>
The Java source (without imports):
public class ImageInfoTask extends Task {
private String outputFile;
private List fileSetList = new ArrayList();
private PrintStream outputFileStream;
public void setOutputFile(String outputFile) {
this.outputFile = outputFile.replace("/", File.separator);
}
public void addFileset(FileSet fileset) {
fileSetList.add(fileset);
}
protected void validate() {
if (outputFile == null) {
throw new BuildException("file not set");
}
if (fileSetList.size() < 1) {
throw new BuildException("fileset not set");
}
}
protected void openOutputFile() throws IOException {
FileOutputStream out = new FileOutputStream(this.outputFile);
// Connect print stream to the output stream
this.outputFileStream = new PrintStream(out, true, "UTF-8");
this.outputFileStream.println("<images>");
}
protected void writeImgToOutputFile(String filename, Dimension dim) {
String imgTag = " <img src=\"/" + filename.replace("\\", "/")
+ "\" height=\"" + dim.height + "\" width=\"" + dim.width
+ "\" />";
this.outputFileStream.println(imgTag);
}
protected void closeOutputFile() {
this.outputFileStream.println("</images>");
this.outputFileStream.close();
}
#Override
public void execute() {
validate();
try {
openOutputFile();
for (Iterator itFSets = fileSetList.iterator(); itFSets.hasNext();) {
FileSet fs = (FileSet) itFSets.next();
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
String[] includedFiles = ds.getIncludedFiles();
for (int i = 0; i < includedFiles.length; i++) {
String filename = includedFiles[i];
Dimension dim = getImageDim(ds.getBasedir() + File.separator + filename);
if (dim != null) {
writeImgToOutputFile(filename, dim);
}
}
}
closeOutputFile();
} catch (IOException ex) {
log(ex.getMessage());
}
}
private Dimension getImageDim(final String path) {
Dimension result = null;
String suffix = this.getFileSuffix(path);
Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix);
if (iter.hasNext()) {
ImageReader reader = iter.next();
try {
ImageInputStream stream = new FileImageInputStream(new File(path));
reader.setInput(stream);
int width = reader.getWidth(reader.getMinIndex());
int height = reader.getHeight(reader.getMinIndex());
result = new Dimension(width, height);
} catch (IOException e) {
log(path + ": " + e.getMessage());
} finally {
reader.dispose();
}
}
return result;
}
private String getFileSuffix(final String path) {
String result = null;
if (path != null) {
result = "";
if (path.lastIndexOf('.') != -1) {
result = path.substring(path.lastIndexOf('.'));
if (result.startsWith(".")) {
result = result.substring(1);
}
}
}
return result;
}
}
I'm not aware of such ant task readily available but it should be relatively simple to write one. In PNG format image size is stored right at the beginning of the file in IHDR header. There are numerous samples of PNG parsers on Google - for example this. Wrap it up in ant task and you're done.