QR code rendering with ZXing.Net.Mobile in Xamarin.Forms app - c#

I'm trying to use ZXing.Net.Mobile to display a QR code as an image.
I'm having difficulty getting the byte[] returned from BarcodeWriter.Writer(...) into an image for display.
i.e. this does not display an image
public class BarcodePage : ContentPage
{
public BarcodePage()
{
Image image = new Image();
image.Source = ImageSource.FromStream(() =>
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = 200,
Width = 600
}
};
var bitmapBytes = writer.Write ("Some text");
return new MemoryStream(bitmapBytes);
});
Content = image;
}
}
The bitmapBytes byte array looks like it has reasonable values in the debugger, how can I turn that into an image for display?
If I change the Image.Source assignment to:
image.Source = ImageSource.FromUri(new Uri("http://i.imgur.com/q0aIYvC.png"));
then it does correctly display the image, so I know the problem isn't with the Forms layout, etc.
Workaround
At the moment, I'm doing conversion to a MemoryStream in the native, e.g. in Android I have:
public class BuildQrCodes_Android : IBuildQrCodes
{
public async Task<MemoryStream> ImageStreamForAsync(string text)
{
var writer = new BarcodeWriter
{
Format = ZXing.BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = 600,
Width = 600
}
};
var bitmap = writer.Write(text);
var stream = new MemoryStream();
await bitmap.CompressAsync(Bitmap.CompressFormat.Png, 100, stream);
stream.Position = 0;
return stream;
}
}
and then over in the Xamarin Forms side, I have
IBuildQrCodes qrBuilder = /* Service lookup */
var stream = await qrBuilder.ImageStreamForAsync("the text to encode");
return ImageSource.FromStream(() => new MemoryStream(stream.ToArray()));
which is doing what I want, so it's an acceptable workaround.

I am not sure what widget "Content" in your code represents, but assigning your "image" to a Form View's Image Class that is a member of your ContentPage should do the trick.
In XAML, you would create an Image within your ContentPage, i.e. like in one of the Form's samples.
Otherwise, dynamically create an Image class widget, add it your layout via AddView for your ContentPage.

Related

how to convert mat to imageSource on UWP

I'm trying to convert mat image to something that I could set as ImageSource on UWP but I could not find any solution.
The only solution I found show me very bad image:
https://i.stack.imgur.com/uB8oT.png
Here's my code:
VideoCapture _capture = new VideoCapture(0);
while (true)
{
using (Mat mat = new Mat())
{
bool ok = _capture.Read(mat);
if (ok)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.High,
async () =>
{
byte[] imageArray = mat.GetRawData();
WriteableBitmap writableBitmap = new WriteableBitmap(mat.Width, mat.Height);
using (MemoryStream memoryStream = new MemoryStream(imageArray))
{
using (Stream stream = writableBitmap.PixelBuffer.AsStream())
{
await memoryStream.CopyToAsync(stream);
}
}
imageCamera.Source = writableBitmap;
});
}
}
how to convert mat to imageSource on UWP
Currently, the Image control only supports images that use BGRA8 encoding and pre-multiplied or no alpha channel. Before attempting to display an image, test to make sure it has the correct format, and if not, use the SoftwareBitmap static Convert method to convert the image to the supported format.
SoftwareBitmap outputBitmap = SoftwareBitmap.CreateCopyFromBuffer(
writeableBitmap.PixelBuffer,
BitmapPixelFormat.Bgra8,
writeableBitmap.PixelWidth,
writeableBitmap.PixelHeight
);
var source = new SoftwareBitmapSource();
await source.SetBitmapAsync(outputBitmap);

Drawing an image from svg url in wpf C#

This is the URL with image-https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/acid.svg
What I have tried
Sample 1-
-I am using SharpVectors package
public void DrawImage()
{
Image svgImage = new Image();
WpfDrawingSettings settings = new WpfDrawingSettings();
settings.IncludeRuntime = false;
settings.TextAsGeometry = true;
FileSvgReader converter = new FileSvgReader(settings);
DrawingGroup drawing = converter.Read(new Uri("https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/acid.svg"));
if (drawing != null)
{
svgImage.Source = new DrawingImage(drawing);
}
}
sample 1 works perfectly but it's latency is very high, So I wanted to improve the performance.
Sample 2 - I tried using bitmap to improve performance below is code, but the issue is I need to download the image or store in folder and use as path as string which works fine but my condition is my URLs are coming form JSON file in .SVG format, they are dynamic and I am not using any .XAMl files for UI.
UI built in code behind programmatically.
Is there any other way I can display SVG image in WPF?
public void DrawImage()
{
Image dynamicImage = new Image();
dynamicImage.Width = 300;
dynamicImage.Height = 200;
stcdock.Children.Add(dynamicImage);
WpfDrawingSettings settings = new WpfDrawingSettings();
settings.IncludeRuntime = true;
settings.TextAsGeometry = false;
string svgTestFile = #"\Downloads\acid.svg";
StreamSvgConverter converter = new StreamSvgConverter(settings);
MemoryStream memStream = new MemoryStream();
if (converter.Convert(svgTestFile, memStream))
{
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = memStream;
bitmap.EndInit();
dynamicImage.Source = bitmap;
}
}
.svg are not nativly supported in wpf.
https://www.nuget.org/packages/svg
This package promisses to add this functionality.

Xamarin Forms Byte[] to Image Source not showing

Hi all I have a byte[] which I save from the Xamarin Essentials Media Picker, I want to display the image on my XAML page so all I have is a blank XAML page with a StackLayout and in my code I do the following:
Stream stream = new MemoryStream(filebyte);
var imageSource = ImageSource.FromStream(() => stream);
Image test = new Image();
test.Source = imageSource;
test.WidthRequest = 50;
test.HeightRequest = 50;
ImageStack.Children.Add(test);
but when the page loads nothing is there. i'm I missing something. I have even tried this on a fresh project using the latest version of Xamarin Forms and Xamarin Essential's
imgByteArray is Byte[], using following code to add image by behind code.
var stream1 = new MemoryStream(imgByteArray);
image.Source = ImageSource.FromStream(() => stream1);
image.WidthRequest = 50;
image.HeightRequest = 50;
imagestack.Children.Add(image);
Update:
Adding one image in Forms, setting Build action as Embedded resource, then converting this image into byte[], using this byte[] for Image to show. I have no problem.
var image = new Xamarin.Forms.Image();
var assembly = this.GetType().GetTypeInfo().Assembly;
byte[] imgByteArray = null;
var s = assembly.GetManifestResourceStream("FormsSample.f19.png");
if (s != null)
{
var length = s.Length;
imgByteArray = new byte[length];
s.Read(imgByteArray, 0, (int)length);
var stream1 = new MemoryStream(imgByteArray);
image.Source = ImageSource.FromStream(() => stream1);
image.WidthRequest = 50;
image.HeightRequest = 50;
imagestack.Children.Add(image);
}

How to override(use) BitmapFrame.Thumbnail property in WPF C#?

Hello! The problem is? that I've got a multipage Tiff file to show, and I use
BitmapFrame.Thumbnail property to show small size thumbnail of every frame(page) of my multipage Tiff file. But< for some reason? the property returns null. Please, give step by step description, of how this should be done?
I've already tried to create my own BitmapSource thumbnail with this method:
public static BitmapImage GetThumbnail(BitmapFrame bitmapFrame)
{
try
{
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
MemoryStream memorystream = new MemoryStream();
BitmapImage tmpImage = new BitmapImage();
encoder.Frames.Add(bitmapFrame);
encoder.Save(memorystream);
tmpImage.BeginInit();
tmpImage.CacheOption = BitmapCacheOption.OnLoad;
tmpImage.StreamSource = new MemoryStream(memorystream.ToArray());
File.WriteAllBytes( $"{Path.GetTempFileName()}.jpg", memorystream.ToArray());
tmpImage.UriSource = new Uri($"{Path.GetTempFileName()}.jpg");
tmpImage.DecodePixelWidth = 80;
tmpImage.DecodePixelHeight = 120;
tmpImage.EndInit();
memorystream.Close();
return tmpImage;
}
catch (Exception ex)
{
return null;
throw ex;
}
}
then I convert the result to BitmapSource and create a list of BitmapFrames using:
List<BitmapFrame> tiffImageList = new List<BitmapFrame>();
tiffImageList.Add(new TiffImage() { index = imageIndex, image = BitmapFrame.Create(frame, (BitmapSource)GetThumbnail(frame))});
In the end I try to get property, but it returns null:
foreach (var tiffImage in tiffImageList)
{
Image image = new Image();
image.Source = tiffImage.image.Thumbnail;
}
I ran into a similar issue, modifying with the SDK PhotoViewerDemo example. Some valid jpg's are shown as white square thumbnails.
I think I found why the question code does not work. Ivan's question provides a correct constructor of BitmapFrame, but the functions have to create a BitmapSource, not a BitmapImage.
C# BitmapFrame.Thumbnail property is null for some images
I got it working with the function provided in that topic, using Ivan's call to the constructor, using the two bitmapsource arguments.
Code in the SDK example I now use is..
private BitmapSource CreateBitmapSource(Uri path)
{
BitmapImage bmpImage = new BitmapImage();
bmpImage.BeginInit();
bmpImage.UriSource = path;
bmpImage.EndInit();
return bmpImage;
}
private BitmapSource CreateThumbnail(Uri path)
{
BitmapImage bmpImage = new BitmapImage();
bmpImage.BeginInit();
bmpImage.UriSource = path;
bmpImage.DecodePixelWidth = 120;
bmpImage.EndInit();
return bmpImage;
}
// it has to be plugged in here,
public Photo(string path)
{
Source = path;
_source = new Uri(path);
// replaced.. Image = BitmapFrame.Create(_source);
// with this:
Image = BitmapFrame.Create(CreateBitmapSource(_source),CreateThumbnail(_source));
Metadata = new ExifMetadata(_source);
}

How to give custom size to PdfSharp generated Pdf

I was trying to generate a pdf from HTML which containing a table using PdfSharp and HTMLRenderer. The following shows the code.
pdf = PdfGenerator.GeneratePdf(html, PageSize.A3);
byte[] fileContents = null;
using (MemoryStream stream = new MemoryStream())
{
pdf.Save(stream, true);
fileContents = stream.ToArray();
return new FileStreamResult(new MemoryStream(fileContents.ToArray()), "application/pdf");
}
Is there any possibility for me to provide a custom size to the PDF and change the orientation of the page. I am using a memory stream to show the PDF directly on the browser display.
You can use the PdfGenerateConfig parameter of the GeneratePdf method to specify a custom page size using the ManualPageSize property.
Use the PageOrientation to get standard page sizes in landscape.
Code from comment:
var config = new PdfGenerateConfig();
config.PageOrientation = PageOrientation.Landscape;
config.ManualPageSize = new PdfSharp.Drawing.XSize(1080, 828);
pdf = PdfGenerator.GeneratePdf(html, config);
I just put this way:
var config = new PdfGenerateConfig()
{
MarginBottom = 100,
MarginLeft = 20,
MarginRight = 20,
MarginTop = 100,
PageSize = PageSize.A4
};
PdfDocument pdf = PdfGenerator.GeneratePdf(html, config);
If I'm not mistaken, PageSize.A3 is not an enum but Rectangle value. So instead of passing predefined Rectangle you can provide your own, for example:
new Rectangle(1191, 842) // for album A3
new Rectangle(842, 595) // for album A4
and so on...

Categories

Resources