Xamarin : Convert image to Pdf format in Xamarin.forms - xamarin

I am getting error width cannot be null , when passing image to inputstream.As i didn't find any alterante method . Basically i want to convert image to Pdf format in Xamarin.forms which supports UWP platform .
I am using xfinium pdf library for this.
public void ConvertJpegToPdf()
{
try
{
PdfFixedDocument document = new PdfFixedDocument();
Xfinium.Pdf.PdfPage page = document.Pages.Add();
page.Width = 800;
page.Height = 600;
var imageStream = GetStream();
PdfJpegImage jpeg = new PdfJpegImage(imageStream);//<-Error
PdfStandardFont helvetica = new PdfStandardFont(PdfStandardFontFace.Helvetica, 24);
PdfBrush brush = new PdfBrush(PdfRgbColor.Red);
page.Graphics.DrawImage(jpeg, 0, 0, page.Width, page.Height);
Stream pdfStream = null;
document.Save(pdfStream);
}
catch (Exception ex)
{
throw ex;
}
}
protected Stream GetStream()
{
byte[] byteArray = Encoding.UTF8.GetBytes("http://david.qservicesit.com/images/3.jpg");
MemoryStream stream = new MemoryStream(byteArray);
return stream;
}
Please suggest some alternate to do this

byte[] byteArray = Encoding.UTF8.GetBytes("http://david.qservicesit.com/images/3.jpg");
You could not get image stream in this way. The method you have used can only get the Bytes of string. For your scenario, you could use http client to acquire image stream. Please refer to the following code:
public async Task<Stream> GetStream()
{
HttpClient client = new HttpClient();
HttpResponseMessage res = await client.GetAsync(new Uri("http://david.qservicesit.com/images/3.jpg"));
Stream stream = await res.Content.ReadAsStreamAsync();
return stream;
}
public async Task ConvertJpegToPdf()
{
try
{
PdfFixedDocument document = new PdfFixedDocument();
Xfinium.Pdf.PdfPage page = document.Pages.Add();
page.Width = 800;
page.Height = 600;
var imageStream = await GetStream();
PdfJpegImage jpeg = new PdfJpegImage(imageStream);
PdfStandardFont helvetica = new PdfStandardFont(PdfStandardFontFace.Helvetica, 24);
PdfBrush brush = new PdfBrush(PdfRgbColor.Red);
page.Graphics.DrawImage(jpeg, 0, 0, page.Width, page.Height);
Stream pdfStream = new MemoryStream();
document.Save(pdfStream);
}
catch (Exception ex)
{
throw ex;
}
}

Related

IMB barcode could not be read

I have tried to read IMB barcode from an image with the below code snippet, but it always return null. I have also tried with the IMB barcode images in the blackbox testing below, but doesn't work.
https://github.com/micjahn/ZXing.Net/tree/master/Source/test/data/blackbox/imb-1
private static void Decode()
{
Bitmap bitmap = new Bitmap(#"\07.png");
try
{
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
byte[] byteArray = memoryStream.GetBuffer();
ZXing.LuminanceSource source = new RGBLuminanceSource(byteArray, bitmap.Width, bitmap.Height);
var binarizer = new HybridBinarizer(source);
var binBitmap = new BinaryBitmap(binarizer);
IMBReader imbReader = new IMBReader();
Result str = imbReader.decode(binBitmap);
}
catch { }
}
I have solved this problem by using the below code snippet shared through the below link.
https://github.com/micjahn/ZXing.Net/issues/59
private static void Decode2()
{
var bitmap = new Bitmap(#"\07.png"); // make sure that the file exists at the root level
try
{
var imbReader = new BarcodeReader
{
Options =
{
PossibleFormats = new List<BarcodeFormat> {BarcodeFormat.IMB}
}
};
var result = imbReader.Decode(bitmap);
if (result != null)
System.Console.WriteLine(result.Text);
else
System.Console.WriteLine("nothing found");
}
catch (System.Exception exc)
{
System.Console.WriteLine(exc.ToString());
}
}

ZXing QR Code Generation in Xamarin Forms PCL

I'm trying to generate and display QR code using ZXing package, I tried in following code I was not able to show QR code. It's showing blank image (transparent).
private void OnGenerateQRCodeButton_Clicked(object sender, EventArgs e)
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = (int)imageCompanyLogo.Height,
Width = (int) imageCompanyLogo.Width,
Margin = 0,
PureBarcode = true
}
};
var bitmap = writer.Write("www.helloworld.com");
imageQRCode.Source = ImageSource.FromStream(() => new MemoryStream(bitmap));
}
Please suggest any way to do it. Thanks.
Create interface in PCL(Xamarin) project for Dependency Service.
Create a class in Native(Xamarin.Droid) and Inherit from PCL Interface.
Implement the method as shown below.
public Stream ConvertImageStream(string text, int width = 300, int height = 300)
{
var barcodeWriter = new ZXing.Mobile.BarcodeWriter
{
Format = ZXing.BarcodeFormat.QR_CODE,
Options = new ZXing.Common.EncodingOptions
{
Width = width,
Height = height,
Margin = 10
}
};
barcodeWriter.Renderer = new ZXing.Mobile.BitmapRenderer();
var bitmap = barcodeWriter.Write(text);
var stream = new MemoryStream();
bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream); // this is the diff between iOS and Android
stream.Position = 0;
return stream;
}
call the method from PCL(Xamarin) project using Dependency Service.
In xaml.cs
private void OnGenerateQRCodeButton_Clicked(object sender, EventArgs e)
{
string barcodeText = "www.helloworld.com";
var stream = DependencyService.Get<IBarCodeServices>().ConvertImageStream(barcodeText, (int)imageCompanyLogo.Width,(int) imageCompanyLogo.Height);
barcodeImage.Source = ImageSource.FromStream(() => stream);
}
Debug and see if stream in empty or not.
var stream = (Stream)null;
private void OnGenerateQRCodeButton_Clicked(object sender, EventArgs e)
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = (int)imageCompanyLogo.Height,
Width = (int) imageCompanyLogo.Width,
Margin = 0,
PureBarcode = true
}
};
using(var bitmap = barcodeWriter.Write("www.helloworld.com"))
{
stream = new MemoryStream();
bitmap.Save(stream, ImageFormat.Png);
stream.Seek(0, SeekOrigin.Begin);
}
imageQRCode.Source = ImageSource.FromStream(() => new MemoryStream(stream));
}

HTTP Post Windows Phone

I'm making a call to an API that consists in a HTTP Post request. The data i want to post is an image, properly converted into a byte array.
The response is not as expected, and i want to know what is the error: is it my code or is it the API? This is the code that i'm using
Image i = new Image();
BitmapImage bi = new BitmapImage(new Uri("/Images/dmoc.jpeg", UriKind.Relative));
testImage.Source = bi;
byte[] rawimage = ImageConverter.ImageToBytes(bi);
try
{
var baseAddress = new Uri("http://private-anon-6cf48a749-yugiohprices.apiary-mock.com/");
using (var httpClient = new HttpClient { BaseAddress = baseAddress })
{
//HttpRequestHeader.ContentType
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpeg"));
using (var response = await httpClient.PostAsync("api/match_card_image", new ByteArrayContent(rawimage)))
{
string responseData = await response.Content.ReadAsStringAsync();
postTxt.Text = responseData;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
MessageBox.Show(ex.StackTrace);
}
where ImageConverter is my class.

Xamarin.Forms get image path

Using the Xamarin.Forms Camera sample from here - https://github.com/XForms/Xamarin-Forms-Labs-Samples/tree/master/XF.Labs.CameraSample i am able to select or take a photo. I then need to convert this image to binary
so here is the code that selects the image:
private async Task SelectPicture()
{
mediaPicker = DependencyService.Get<IMediaPicker>();
imageSource = null;
var mediaFile = await mediaPicker.SelectPhotoAsync(new CameraMediaStorageOptions
{
DefaultCamera = CameraDevice.Front,
MaxPixelDimension = 400
});
imageSource = ImageSource.FromStream(() => mediaFile.Source);
img.Source = imageSource;
}
and the code that takes the image is very similar
private async Task TakePicture()
{
mediaPicker = DependencyService.Get<IMediaPicker>();
imageSource = null;
var mediaFile = await mediaPicker.TakePhotoAsync(new CameraMediaStorageOptions
{
DefaultCamera = CameraDevice.Front,
MaxPixelDimension = 400
});
imageSource = ImageSource.FromStream(() => mediaFile.Source);
img.Source = imageSource;
}
How do i get the actual string imagePath from the above so that i can call the DependencyService below?
public byte[] ImageToBinary(string imagePath)
{
FileStream fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
fileStream.Close();
return buffer;
}
Shouldn't do this stuff tired
It is built in to the MediaFile so the answer is simply mediaFile.Path.ToString();
mediaFile.Path will give you the actual path

Passing cookies to Image.GetInstance

Using image handler to convert relative path to absolute.
protected byte[] ConvertHTMLToPDF(string HTMLCode)
{
if (Request.Url == null)
throw new Exception();
var doc = new Document(PageSize.A4);
doc.Open();
var interfaceProps = new Hashtable();
var ih = new ImageHander {BaseUri = Request.Url.ToString()};
interfaceProps.Add("img_provider", ih);
foreach (IElement element in HTMLWorker.ParseToList(new StringReader(HTMLCode), null, interfaceProps))
{
doc.Add(element);
}
var _xmlr = new XmlTextReader(new StringReader(HTMLCode));
HtmlParser.Parse(doc, _xmlr);
var stream = new MemoryStream();
PdfWriter.GetInstance(doc, stream);
doc.Close();
return stream.ToArray();
}
class:
public class ImageHander : IImageProvider
{
public string BaseUri;
public Image GetImage(string src, Hashtable h, ChainedProperties cprops, IDocListener doc)
{
string imgPath;
if (src.ToLower().Contains("http://") == false)
imgPath = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + src;
else
imgPath = src;
return Image.GetInstance(imgPath);
}
}
imgPath at the end is correct. But it's not static file, it's url of action that returns image, so I need to pass cookies when requesting image. Is it possible?
Yes, it is possible, but you're gonna have to send the request yourself and not rely on the Image.GetInstance method. For example using the HttpClient you could send cookies along with the request:
var imageUrl = new Uri(imagePath);
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler))
{
cookieContainer.Add(
new Uri(imageUrl.GetLeftPart(UriPartial.Authority)),
new Cookie("CookieName", "cookie_value")
);
var response = client.GetAsync(imageUrl).Result;
response.EnsureSuccessStatusCode();
Stream imageStream = response.Content.ReadAsStreamAsync().Result;
// You've got the Stream here, read the documentation of iTextSharp
// how to create an Image instance from a Stream:
return Image.FromStream(imageStream); // ?????
// or maybe there's a method allowing you to create an Image from byte[]
byte[] imageData = new byte[imageStream.Length];
imageStream.Read(imageData, 0, imageData.Length);
return Image.FromByteArray(imageData); // ?????
}

Resources