I am working on an android project in which I want to take the screen shot of current activity and save that as .jpeg file in my android device.
When I use instance of FileOutputStream to write the stream of bitmap image into a file, it gives me following error
Argument 3 cannot converted from 'Java.IO.FileOutputStream' to 'System.IO.Stream'
My code
private void ShareButton_Click(object sender, EventArgs e)
{
//create a bitmap screen capture
View screen = FindViewById(Resource.Layout.AboutImage);
Bitmap bitmap = Bitmap.CreateBitmap(screen.GetDrawingCache(false));
screen.SetWillNotCacheDrawing(true);
image = new File(directory, "Eco_Friendly " + mc.identifier);
FileOutputStream outputstream = new FileOutputStream(image);
int quality = 100;
bitmap.Compress(Bitmap.CompressFormat.Jpeg, quality, outputstream);//Here is error
}
Q:How to solve this problem?
Try this code:
package com.screen.shots;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class CaptureScreenShots extends Activity {
LinearLayout L1;
ImageView image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screen_shots);
L1 = (LinearLayout) findViewById(R.id.LinearLayout01);
Button but = (Button) findViewById(R.id.munchscreen);
but.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
View v1 = L1.getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bm = v1.getDrawingCache();
BitmapDrawable bitmapDrawable = new BitmapDrawable(bm);
image = (ImageView) findViewById(R.id.screenshots);
image.setBackgroundDrawable(bitmapDrawable);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.screen_shots, menu);
return true;
}
}
Result:
like this
View root = getWindow().getDecorView().getRootView();
root.setDrawingCacheEnabled(true);
root.buildDrawingCache();
Bitmap snapshot = root.getDrawingCache();
at last, you should call this
root.destroyDrawingCache();
Related
I want to create an QrCode using IronBarCode, and then save it as a Stream or Byte[].
However both methods expect the file to be saved prior to creation:
var absolute = Request.Scheme + "://" + Request.Host + url;
var qrcode = IronBarCode.QRCodeWriter.CreateQrCode(absolute);
qrcode.AddAnnotationTextAboveBarcode(device.Name);
qrcode.AddBarcodeValueTextBelowBarcode(absolute);
var f = qrcode.ToJpegStream();
var y = qrcode.ToJpegBinaryData();
ToJpegStream() and ToJpegBinaryData expects the absolute string to be an actual file path. I want to create a QrCode and save it as a Byte[] or Stream, however the error thrown is "The filename, directory name, or volume label syntax is incorrect."
AddBarcodeValueTextBelowBarcode method parameter for string is FontPath. That is why it was trying to find the font file that does not exist.
string absolute = "https://ironsoftware.com/";
string Name = "Product URL:";
//Add Annotation(text) below the generated barcode
var qrcode = QRCodeWriter.CreateQrCode(absolute);
qrcode.AddAnnotationTextBelowBarcode(Name);
qrcode.ToJpegBinaryData();
//Add Barcode value below the generated barcode
var qrcode = QRCodeWriter.CreateQrCode(absolute);
qrcode.AddBarcodeValueTextBelowBarcode();
qrcode.ToJpegBinaryData();
The below image is FontPath. FontPath is actually the directory path that actually lead to the Font file.
//This will add Barcode value into QRCode
.AddBarcodeValueTextBelowBarcode()
If you want to add absolute path to the QRCode you should use
//This will add your text to Barcode
.AddAnnotationTextBelowBarcode(absolute)
For more information on how to use the method please refer to the API reference:
https://ironsoftware.com/csharp/barcode/object-reference/api/IronBarCode.GeneratedBarcode.html#IronBarCode_GeneratedBarcode_AddBarcodeValueTextBelowBarcode
The issue mentioned isn't reproducible with the code provided. The code below is adapted from your code and the from the example. It's been tested.
Create a new Windows Forms App (.NET Framework)
Download/install NuGet package: Barcode
Add a Button to Form1 (name: btnCreateQRCode)
Add a PictureBox to Form1 (name: pictureBox1)
Add using directives:
using IronBarCode;
using System.IO;
Form1.cs:
public partial class Form1 : Form
{
private byte[] _qrCode = null;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private byte[] CreateBarCode(string url, string annotationText)
{
//create new instance
GeneratedBarcode qrCode = QRCodeWriter.CreateQrCode(url);
qrCode.AddAnnotationTextAboveBarcode(annotationText);
qrCode.AddBarcodeValueTextBelowBarcode(url);
byte[] qrCodeBytes = qrCode.ToJpegBinaryData();
return qrCodeBytes;
}
private void btnCreateQRCode_Click(object sender, EventArgs e)
{
_qrCode = CreateBarCode("https://www.google.com/search?q=how+to+search", "How To Search");
using (MemoryStream ms = new MemoryStream(_qrCode))
{
pictureBox1.Image = Image.FromStream(ms);
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; //fit to size
pictureBox1.Refresh();
}
}
}
Resources:
Create QR Code
I use a sample to play gifs in my app,
but start(), stop() and pause() methods not working.
sample: enter link description here
nuget package: Install-Package Karamunting.Android.Koral.AndroidGifDrawable
This is my code
enter image description here
Thanks for helping me...
🎊 Welcome to SO 🎊
That exception thrown because you casts wrong object to wrong Type (GifDrawable).
To achieve what you want, you have to get Drawable object first by accessing GifImageView.Drawable property and then cast it to GifDrawable.
Now you can access those methods (.Stop(), .Start()) correctly.
Sample code:
var gifImageView0 = FindViewById<GifImageView>(Resource.Id.gif6);
var stop = FindViewById<Button>(Resource.Id.button1);
stop.Click += (s, e) =>
{
//
(gifImageView0.Drawable as GifDrawable)?.Stop();
};
Welcome to SO!
I have checked the Karamunting.Android.Koral.AndroidGifDrawable Nuget Package, it seems not providing the guides for Xamarin Android to invoke it. And there is only 721 downloads. After testing in my local site, it has many errors when using its methods shared from GitHub. I think it will need more time to solve problems about specified cast is not valid.
Therefore, I will suggest that installing Refractored.GifImageView from JamesMontemagno. I have test that in local site, and it wroks so conveniently.And you can refer to its GitHub to know how to use in Xamarin Android.
Install it:
Sample code as follows:
public class MainActivity : AppCompatActivity
{
Felipecsl.GifImageViewLibrary.GifImageView gifImageView;
//PL.DroidsOnRoids.Gif.GifImageView gifImageViewTrans;
Button btnToggle;
Button btnStart;
Button btnStop;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
gifImageView = FindViewById<Felipecsl.GifImageViewLibrary.GifImageView>(Resource.Id.gifImageView);
//gifImageViewTrans = FindViewById<PL.DroidsOnRoids.Gif.GifImageView>(Resource.Id.gifImageView2);
btnToggle = FindViewById<Button>(Resource.Id.btnToggle);
btnStart = FindViewById<Button>(Resource.Id.btnStart);
btnStop = FindViewById<Button>(Resource.Id.btnStop);
// From Drawable
Stream input = Resources.OpenRawResource(Resource.Drawable.timg);
// You should convert the "input" into Byte Array
byte[] bytes = ConvertByteArray(input);
gifImageView.SetBytes(bytes);
gifImageView.StartAnimation();
btnToggle.Click += (sender, e) =>
{
try
{
if (gifImageView.IsAnimating)
gifImageView.StopAnimation();
else
gifImageView.StartAnimation();
}
catch (Exception ex)
{
}
};
btnStart.Click += BtnStart_Click;
btnStop.Click += BtnStop_Click;
}
private void BtnStop_Click(object sender, EventArgs e)
{
gifImageView.StopAnimation();
}
private void BtnStart_Click(object sender, EventArgs e)
{
gifImageView.StartAnimation();
}
private byte[] ConvertByteArray(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, read);
return ms.ToArray();
}
}
}
The effect:
I'm using a webcam to capture an image and place it to picturebox and save the image to my project folder and get the image path then save to sql database. The problem is i do not know how i gonna update/overwrite the existing file
NOTE: My data is bind in datagridview when i click the cell the image will be retrieved on another form, so basically it based on the ID.
Here's what i've tried to achieve that
private void BtnOk_Click(object sender, EventArgs e)
{
if (picCapturedImage.Image != null)
{
using (var bitmap = new Bitmap(picCapturedImage.Image))
{
bitmap.Save(Common.CustomerPath, ImageFormat.Png);
_updCustomer.picCustomerImage.Image = Image.FromFile(Common.CustomerPath);
}
}
Close();
}
When i run this code it replace the image of User.Png not the capture image(Image1, Image2, etc)
User.Png is my default image when user doesn't want to browse or capture an image
Here's the code for saving the image in the project folder
I used loop to avoid overwriting the image in the project folder, so when i saved the image
Image0, Image1, Image2, etc
if (picCapturedImage.Image != null) {
using (var bitmap = new Bitmap(picCapturedImage.Image))
{
for (int i = 0; i < int.MaxValue; i++)
{
var fileName = $#"..\..\Resources\Photos\Image{i}.png";
if (!File.Exists(fileName)) {
bitmap.Save(fileName, ImageFormat.Png);
Common.CustomerPath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $#"..\..\Resources\Photos\Image{i}.png"));
_regCustomer.picCustomerImage.Image = Image.FromFile(Common.CustomerPath);
break;
}
}
}
}
Close();
Here's the code where i save the path
public class Common
{
public static string CustomerPath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"..\..\Resources", "User.png"));
}
Here's the code for retrieving the image path
_updCustomer.picCustomerImage.Image = Image.FromFile(customer.ImagePath);
I just pass the image between two pages, by passing the byte[] and I try to convert the byte[] to image in page 2 using the following code,
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.Uri.OriginalString.Contains("img"))
{
expenseDetails = AuthOrgClass.expenseDetails;
imgData = NavigationService.GetImageNavigationData();
fill();
}
}
private void fill()
{
var bitmapImage = new BitmapImage();
var memoryStream = new MemoryStream(imgData);
bitmapImage.SetSource(memoryStream);
ImageBox.Source = bitmapImage;
}
While executing the line bitmapImage.SetSource(memoryStream);
I get the exception
An exception of type 'System.Exception' occurred in System.Windows.ni.dll but was not handled in user code
What could be the problem?
You should use IsolatedStorageSettings to store image as byte array. IsolatedStorageSettings accessible in all application. So you can easily pass your byte array between any pages in application. try this may this will help you.
SaveImageAsByteArray()
{
IsolatedStorageSettings MemorySettings = IsolatedStorageSettings.ApplicationSettings;
if (MemorySettings.Contains("ImageData"))
MemorySettings["ImageData"] = your byte array;
else
MemorySettings.add("ImageData", your byte array;);
IsolatedStorageSettings.ApplicationSettings.Save();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.Uri.OriginalString.Contains("img"))
{
fill();
}
}
private void fill()
{
IsolatedStorageSettings MemorySettings = IsolatedStorageSettings.ApplicationSettings;
if (MemorySettings.Contains("ImageData"))
byte[] bytes = MemorySettings["ImageData"]
MemoryStream stream = new MemoryStream(bytes);
BitmapImage image = new BitmapImage();
image.SetSource(stream);
ImageBox.Source = image;
}
The best Practice is take a global Image varible in App.xaml.cs,assign it at first page and take value from it at second page.It would never create a problem..:)
In my windows 8 application(C#), I want to capture images (I done) and then save it to a Sqlite database. As Sqlite is not supporting BipmapImage, Uri types etc (I tried but giving exceptions of not supported storage..) How can I do this?
I simply want to save images in local database that I have captured using camera and then retrieve these images (set to binding). Please suggest me other options to achieve this.
I also tried to convert Uri into string and then saving this string into SQLite db and then again converting string to Uri and then making Bitmap images but I couldn't achieve this (is it a right approach ?).
If you can share me any sample please do it. I spent many hours in it but don't know where I am doing wrong!
Thanks Zauk
Although I do not prefer to save images in a database.
But if you want to save images in the database then one way of doing this is to convert your images to base64 string and then save the string in SQLite database.
public string ConvertToString(Image image)
{
// First Convert image to byte array.
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
image.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(byteArray);
return base64String;
}
You can save camera captured image into SQLitedatabase in this way..
public class CamActivity extends Activity {
byte[] byteArray;
private static final int CAMERA_REQUEST = 1888;
protected static final int TAKE_PHOTO_CODE = 0;
public ImageView imageView;
private DBAdapter db;
byte [] imgbyte;
EditText txtView ;
String name;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db=new DBAdapter(CamActivity.this);
db.open();
this.imageView = (ImageView)this.findViewById(R.id.imageView1);
txtView=(EditText)findViewById(R.id.editText1);
Button B = (Button) this.findViewById(R.id.camera);
B.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
// cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,getImageUri());
startActivityForResult(cameraIntent,CAMERA_REQUEST );
}
});
Button save = (Button)findViewById(R.id.saving);
save.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
name=txtView.getText().toString();
try
{
db.insertImageDetails(byteArray,name);
}
catch (Exception e) {
e.printStackTrace();
}
//mySQLiteAdapter.close();
Toast.makeText(getApplicationContext(), "processing", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), "image saved", Toast.LENGTH_SHORT).show();
}});
Button G = (Button) this.findViewById(R.id.get);
G.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
Intent intent= new Intent(CamActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//final byte[] byteArray;
if (requestCode == CAMERA_REQUEST) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
//imageView.setImageBitmap(photo);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
byteArray = stream.toByteArray();
System.out.println(byteArray);
Toast.makeText(getApplicationContext(), byteArray.toString(), Toast.LENGTH_SHORT).show();
}
}
}