What is the C# equivalent of the following Java snippet below:
Drawable image;
URL imageUrl;
imageUrl = new URL(getMyImageUrl(imageNumber));
Bitmap bitmap = BitmapFactory.decodeStream(imageUrl.openStream());
image = new BitmapDrawable(bitmap);
Thanks in advance.
A more literal conversion to C# would be:
var imageUrl = new Java.Net.URL(GetMyImageUrl(imageNumber));
var bitmap = Android.Graphics.BitmapFactory.DecodeStream (imageUrl.OpenStream ());
var image = new Android.Graphics.Drawables.BitmapDrawable (bitmap);
This is one of the strengths of Mono for Android: the classes and methods mirror the underlying Java platform (with some exceptions) while providing much of the .NET framework, so migrating code from Java to C# should be reasonably straightforward.
using System.Drawing;
using System.Drawing.Imaging;
public Bitmap DownloadImage(string imageUrl)
{
try
{
WebClient client = new WebClient();
using(Stream stream = client.OpenRead(imageUrl))
{
Bitmap bitmap = new Bitmap(stream);
}
}
catch(Exception)
{
//todo: handle me
throw;
}
return bitmap
}
Have a look at http://www.dreamincode.net/code/snippet2555.htm . I assumed you would want to use Bitmap. I have never used Drawable in Java, so correct me if I'm wrong.
Related
I want to get UIImage from Asset Library Url
I'm an developing app in xamarin ios, trying to get a UIImage Object from a given Asset-Library-Url.
Picked multiple images from gallery using ELCImagePickerViewController.
All image paths are added in string array list.
Now i need to get all the images in Byte[] using the Asset-Library-Url path.
The given Url is:
assets-library://asset/asset.JPG?id=0E126068-14F9-431F-91B5-8BC397727656&ext=JPG
I tried it with the following approach :
static UIImage FromUrl(string uri)
{
using (var url = new NSUrl(uri))
using (var data = NSData.FromUrl(url))
return UIImage.LoadFromData(data);
}
But it always returns null.
Can anybody please tell me what i'm doing wrong here?
These Urls are for the ALAssetsLibrary, you will need to use the ALAssetsLibrary to access them. See example below:
public Byte[] LoadAssetAsByteArray(string uri)
{
var nsUrl = new NSUrl(uri);
var asset = new ALAssetsLibrary();
Byte[] imageByteArray = new Byte[0];
UIImage image;
asset.AssetForUrl(nsUrl,(ALAsset obj) => {
var assetRep = obj.DefaultRepresentation;
var cGImage = assetRep.GetFullScreenImage();
image = new UIImage(cGImage);
// get as Byte[]
imageByteArray = new Byte[image.AsPNG().Length];
//imageView.Image = image;
},
(NSError err) => {
Console.WriteLine(err);
});
return imageByteArray;
}
There is a great recipe using a UIImagePickerController on the Xamarin Site which I beleive would help you
I'm trying to use ZXing on UWP project and I have read a lots of tutorials, that I can't get to work. The last tutorial said that I should use WritableBitmap, 'cos Bitmap is not awailable in UWP.
However it says to me
Cannot convert type 'Windows.UI.Xaml.Media.Imaging.WriteableBitmap' to
'ZXing.LuminanceSource'
public class QrCodeHelpers
{
public static void ReadQrCodeFromBitmap(WriteableBitmap image)
{
IBarcodeReader reader = new BarcodeReader();
var generic = new BarcodeReaderGeneric<WriteableBitmap>();
// detect and decode the barcode inside the bitmap
var result = reader.Decode((ZXing.LuminanceSource)image);
// do something with the result
}
}
How could I get this work? I have an image from MediaCapture and it would be fine to use that and get the QR code's data. Any solution?
First of all, I agree with Peter Duniho.
Then, if you want to use reader.Decode() method, the parameter is actually SoftwareBitmapLuminanceSource.
You can convert the WriteableBitmap to SoftwareBitmap at first and then convert it to SoftwareBitmapLuminanceSource. And in your code IBarcodeReader reader = new BarcodeReader();, is this a typo? IBarcodeReader is an interface.
Any way, you can code for example like this:
SoftwareBitmap sbmp = SoftwareBitmap.CreateCopyFromBuffer(wbmp.PixelBuffer,
BitmapPixelFormat.Bgra8,
wbmp.PixelWidth,
wbmp.PixelHeight); //converter WriteableBitmap to SoftwareBitmap, wbmp represents the WriteableBitmap
//convert SoftwareBitmap to SoftwareBitmapLuminanceSource
SoftwareBitmapLuminanceSource luminanceSource = new SoftwareBitmapLuminanceSource(sbmp);
BarcodeReader reader = new BarcodeReader(); //change IBarcodeReader to BarcodeReader
var generic = new BarcodeReaderGeneric<WriteableBitmap>(); //This code for what?
var result = reader.Decode(luminanceSource);
Any executable funtion to convert from base64 to an image using c# windows 8.1************* .
I tried :
public Image byteArrayToImage(byte[] byteArrayIn)
{
Image returnImage = null;
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
returnImage = Image.FromStream(ms);
}
return returnImage;
}
FromStream not suitable for windows 8.1
First of all, the Windows.UI.Xaml.Controls.Image class is a control object, not an actual bitmap-type object. What you actually want is a BitmapImage. Of course, given this misunderstanding, you're likely to run into other problems with your code; you don't show the caller of this method, but if you've confused the type here, you've probably confused it elsewhere. So that will have to be fixed.
Secondly, as is the case with many things in WinRT, doing what you want is somewhat more complicated than if you were using the desktop API. :(
That said, something like this should work:
public Windows.UI.Xaml.Media.Imaging.BitmapImage byteArrayToImage(byte[] byteArrayIn)
{
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await stream.WriteAsync(byteArrayIn.AsBuffer(0, byteArrayIn.Length));
stream.Seek(0);
BitmapImage image = new BitmapImage();
await image.SetSourceAsync(stream);
return image;
}
}
Then you can set that object to the Source property of an Image control object.
Some notes:
In your original example, disposing the source stream is at the very least unconventional. My recollection is that in at least some cases, doing so isn't legal, as the Bitmap object returned requires the Stream instance to remain undisposed. For WinRT, AFAIK disposing the stream after the bitmap has been initialized is fine.
The AsBuffer() method is an extension method. You'll need to include a using System.Runtime.InteropServices.WindowsRuntime; in your code if it's not already there for it to work.
See also:
BitmapSource class
InMemoryRandomAccessStream class
WindowsRuntimeBufferExtensions Class
I'm in the process of integrating ZXing.NET into a WPF application but I'm using the BarcodeReader.Decode method to read the QR barcode. It works but now I'm wondering what happens when the image have multiple QR barcodes. I want ZXing to read them all into an array. Is this possible? If yes, how? I don't see any method that does this.
Edit:
I found out there is a class called QRCodeMultiReader that I can use to read multiple QR barcodes. But the parameter that you send to the decodeMultiple method is of type ZXing.BinaryBitmap. How do I convert a Bitmap into a BinaryBitmap?
Here is what I have, but the results variable is always null when I call decodeMultiple:
public static List<BarCodeDataContract> MultipleDecode(Bitmap image)
{
var converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(image, typeof(byte[]));
LuminanceSource source = new RGBLuminanceSource(bytes, image.Width, image.Height);
var binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
var reader = new QRCodeMultiReader();
var results = reader.decodeMultiple(binaryBitmap);
var scannedQrBarcodes = new List<BarCodeDataContract>();
foreach (var result in results)
{
if (result == null || result.BarcodeFormat != BarcodeFormat.QR_CODE || !result.Text.Contains(":")) return null;
var qrCodeData = result.Text.Split(':');
if (qrCodeData.Length != 2) return null;
int numericCode;
if (int.TryParse(qrCodeData[0], out numericCode))
{
if (System.Enum.IsDefined(typeof(QrCodeActionPrefixType), (short)numericCode))
{
Guid guid;
if (Guid.TryParse(qrCodeData[1], out guid))
{
scannedQrBarcodes.Add(new BarCodeDataContract()
{
QrCodeActionPrefixType = (QrCodeActionPrefixType)numericCode,
BarCodeObjectUniqueId = guid
});
}
}
}
}
return scannedQrBarcodes;
}
You can create a new BinaryBitmap by using a Binarizer that processes a LuminanceSource. These are all ZXing related classes.
To get the LuminanceSource you can create a new BitmapLuminanceSource that you pass your Bitmap. (BitmapLuminanceSource' base class is BaseLuminanceSource which base class is LuminanceSource, that is what you want)
The Binarizer turns your LuminanceSource into a BinaryBitmap. This means the resulting image will only have black and white pixels or dots (binary). There are multiple ways to binarize an image and some ways are more suited for other conditions, like a dark background for example. You can try out different Binarizers.
Code:
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BitmapLuminanceSource(_insert your Bitmap here_)));
The BarcodeReader class implements two interfaces: IBarcodeReader and IMultipleBarcodeReader.
The IMultipleBarcodeReader interface supports the method DecodeMultiple.
If you set the Property PossibleFormats only to QR_CODE the BarcodeReader uses internally the QRCodeMultiReader implementation if DecodeMultiple is called. If you look for other barcode types it uses the GenericMultipleBarcodeReader.
Btw. if the QR_CODEs are generated with Structured Append support you will find in the ResultMetadata collection the sequence number and parity information for every result which is found. That information helps to build up the final result in the correct order if needed.
I am using an Epson Perfection V700 scanner and selecting the following options when scanning using their tool:
ICM Color correction (source: EPSON-Standard and target: sRGB)
Unsharp Mask (medium)
That produces this image:
Now my problem is this - I actually need to interact with this scanner using TWAIN .Net and when I do so, the image I get back is this:
Aside: I unselected the aforementioned two options and scanned again with the Epson and got a very similar image to what I get through TWAIN.
So I figure that perhaps these are post processing steps that I can do myself on the image (maybe they are done in the hardware somehow though, I don't know).
I am using EmguCV so first of all I created an extension method that applies the ICM (I struggled to find any documentation for this, so it is a bit of a guess and maybe I am wrong straight away but I got the information from here: The bitmap transform class and it seems to make a difference to the image):
public static Image<Bgr, TDepth> ApplyIcm<TDepth>(
this Image<Bgr, TDepth> source,
string sourceIcm,
string targetIcm)
where TDepth : new()
{
var target = source.CopyBlank();
using (source)
{
using (var b = source.Bitmap)
{
using (var memory = new MemoryStream())
{
b.Save(memory, ImageFormat.Bmp);
memory.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
var ccb = new ColorConvertedBitmap();
ccb.BeginInit();
ccb.Source = bitmapImage;
ccb.SourceColorContext =
new ColorContext(new Uri(sourceIcm));
ccb.DestinationColorContext =
new ColorContext(new Uri(targetIcm));
ccb.EndInit();
var encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(ccb));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
target.Bitmap = new Bitmap(ms);
}
}
}
}
return target;
}
Then I looked at that unsharpen thing and came across this question: How to sharpen an image in OpenCV? which says:
You use a gaussian smoothing filter and subtract the smoothed version from the original image
(I also checked this question to find out what the equivalent emgucv call is Why might EmguCV Gaussian blur not return identical results as OpenCV Gaussian blur?) and came up with this additional extension method:
public static Image<Bgr, TDepth> UnsharpMask<TDepth>(
this Image<Bgr, TDepth> source,
Size kernelSize,
int kernelHoritonalStandardDeviation,
int kernelVerticalStandardDeviation,
double alpha,
double beta,
double gamma)
where TDepth : new()
{
Image<Bgr, TDepth> ret = source.CopyBlank();
CvInvoke.cvSmooth(source,
ret,
SMOOTH_TYPE.CV_GAUSSIAN,
kernelSize.Width,
kernelSize.Height,
kernelHoritonalStandardDeviation,
kernelVerticalStandardDeviation);
CvInvoke.cvAddWeighted(source, alpha, ret, beta, gamma, ret);
return ret;
}
Now I call it like so:
string sourceIcm = #"C:\Windows\System32\spool\drivers\color\ewrgb18.icm";
string targetIcm = #"C:\Windows\System32\spool\drivers\color\ewsrgb.icm";
using(var im = new Image<Bgr, byte>("out.bmp"))
{
using (var icmmed = im.ApplyIcm(sourceIcm, targetIcm))
{
using (var ret = icmmed.UnsharpMask(new Size(0, 0), 5, 5, 2.4, -1.5, 0))
{
ret.Save("ret.bmp");
}
}
}
and this is the result:
Not very good! :-(
I have fiddled with the parameters endlessly but I just cannot work out how (or even if) I can achieve the same result as the Epson tool.
So, my question is:
Does anyone know if it is possible to achieve a result using opencv/emgucv (or even TWAIN - I had a look through the documentation for that and tried adjusting some of the capability parameters but I just made the image worse) that is similar in sharpness to the original image above or is there another technique I should try (could it be that I would need to know some details about the hardware itself in order to achieve correct sharpening)?
I think you should know how using WIA (Windows Image Acquisition) in your project, you may don't need to get access to hardware using opencv. WIA is used for integrating with webcams and scanners. Or, you can use TWAIN as you mentioned
have a look at these examples they could by helpful for your project:
using WIA
and
using TWAIN
Concerning the sharpening, you can use opencv functionality at software level, as another choice to solve your problem