How Can I edit image to android gallery and save - imageview

I access the android gallery and select image. after view photo on image view ..
this code is true work.
targetImage = (ImageView)findViewById(R.id.imageView1);
public void Onclickimage(View view){
try{
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}
catch (Exception ex)
{
Toast.makeText(this,ex.getMessage(),Toast.LENGTH_LONG).show();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
targetImage.setImageBitmap(BitmapFactory.decodeFile(picturePath));
}
I would like another buttonclick set text on photo to imageview.
This code does not work.
public void onClick(View view) {
Bitmap bmp = drawTextToBitmap(MainActivity.this,R.id.imageView1,"MyText");
targetImage.setImageBitmap(bmp);
}
public Bitmap drawTextToBitmap(Context mContext, int resourceId, String mText) {
try {
Resources resources = mContext.getResources();
float scale = resources.getDisplayMetrics().density;
ImageView img = (ImageView)findViewById(R.id.imageView1);
float xson = img.getWidth();
float yson = img.getHeight();
Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.BLACK);
// text size in pixels
paint.setTextSize((int) (12 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(mText, 0, mText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width())/4;
int y = ((bitmap.getHeight() + bounds.height())/3)+50;
paint.setColor(Color.RED);
canvas.drawRect(x * scale-15, y * scale-30,xson+15 - x * scale , yson, paint); // for background
paint.setColor(Color.BLACK); for text
canvas.drawText(mText, x * scale, y * scale, paint);
return bitmap;
} catch (Exception e) {
Toast.makeText(MainActivity.this,e.toString(),Toast.LENGTH_LONG).show();
return null;
}
I write R.id.imageview1 instead to R.drawable.recimage this code is work but for just one photo.

I solve the problem
this code is wrong
Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId);
true code
img.setDrawingCacheEnabled(true);
Bitmap bitmap = img.getDrawingCache();

Related

How do you print TextArea to a USB Thermal Printer 58mm?(JAVAFX)

So I'm trying to make a billing system in which I want to print a receipt.I was able to do it with some code that I found online,but the font size is too big to print in the 58mm wide paper.I'm not able to adjust the font size.Any kind of help with this issue will be highly appreciated.Thank You.
Here is The Code :
public class PrinterService implements Printable {
public List<String> getPrinters(){
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
PrintService printServices[] = PrintServiceLookup.lookupPrintServices(
flavor, pras);
List<String> printerList = new ArrayList<String>();
for(PrintService printerService: printServices){
printerList.add( printerService.getName());
}
return printerList;
}
#Override
public int print(Graphics g, PageFormat pf, int page)
throws PrinterException {
if (page > 0) { /* We have only one page, and 'page' is zero-based */
return NO_SUCH_PAGE;
}
/*
* User (0,0) is typically outside the imageable area, so we must
* translate by the X and Y values in the PageFormat to avoid clipping
*/
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/* Now we perform our rendering */
g.setFont(new Font("Roman", 0, 8));
g.drawString("Hello world !", 0, 10);
return PAGE_EXISTS;
}
public void printString(String printerName, String text) {
// find the printService of name printerName
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
PrintService printService[] = PrintServiceLookup.lookupPrintServices(
flavor, pras);
PrintService service = findPrintService(printerName, printService);
DocPrintJob job = service.createPrintJob();
try {
byte[] bytes;
// important for umlaut chars
bytes = text.getBytes("CP437");
Doc doc = new SimpleDoc(bytes, flavor, null);
job.print(doc, null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void printBytes(String printerName, byte[] bytes) {
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
PrintService printService[] = PrintServiceLookup.lookupPrintServices(
flavor, pras);
PrintService service = findPrintService(printerName, printService);
DocPrintJob job = service.createPrintJob();
try {
Doc doc = new SimpleDoc(bytes, flavor, null);
job.print(doc, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private PrintService findPrintService(String printerName,
PrintService[] services) {
for (PrintService service : services) {
if (service.getName().equalsIgnoreCase(printerName)) {
return service;
}
}
return null;
}
}
#FXML
public void printit(ActionEvent actionEvent)
{
PrinterService printerService = new PrinterService();
System.out.println(printerService.getPrinters());
//print some stuff
printerService.printString("POS-58-Series", area.getText());
}

resize image without losing quality MVC 4

I just want to re-size image without losing quality
can I use this ?
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
WebImage img = new WebImage(file.InputStream);
if (img.Width > 1000)
img.Resize(1000, 1000);
img.Save("path");
return View();
}
or WebImage resize but loss image quality ?
thanks
Here is a code I use. Call ResizeImage method in your action.
public class Size
{
public Size(int width, int height)
{
Width = width;
Height = height;
}
public int Width { get; set; }
public int Height { get; set; }
}
public static bool ResizeImage(string orgFile, string resizedFile, ImageFormat format, int width, int height)
{
try
{
using (Image img = Image.FromFile(orgFile))
{
Image thumbNail = new Bitmap(width, height, img.PixelFormat);
Graphics g = Graphics.FromImage(thumbNail);
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle rect = new Rectangle(0, 0, width, height);
g.DrawImage(img, rect);
thumbNail.Save(resizedFile, format);
}
return true;
}
catch (Exception)
{
return false;
}
}
Taken from http://www.codeproject.com/Tips/481015/Rename-Resize-Upload-Image-ASP-NET-MVC.
It is say to firstly create a class for image to save (I have just copy and paste)
public class ImageResult
{
public bool Success { get; set; }
public string ImageName { get; set; }
public string ErrorMessage { get; set; }
}
then you need another class with method to save (i have just copy and paste)
public class ImageUpload
{
// set default size here
public int Width { get; set; }
public int Height { get; set; }
// folder for the upload, you can put this in the web.config
private readonly string UploadPath = "~/Images/Items/";
public ImageResult RenameUploadFile(HttpPostedFileBase file, Int32 counter = 0)
{
var fileName = Path.GetFileName(file.FileName);
string prepend = "item_";
string finalFileName = prepend + ((counter).ToString()) + "_" + fileName;
if (System.IO.File.Exists
(HttpContext.Current.Request.MapPath(UploadPath + finalFileName)))
{
//file exists => add country try again
return RenameUploadFile(file, ++counter);
}
//file doesn't exist, upload item but validate first
return UploadFile(file, finalFileName);
}
private ImageResult UploadFile(HttpPostedFileBase file, string fileName)
{
ImageResult imageResult = new ImageResult { Success = true, ErrorMessage = null };
var path =
Path.Combine(HttpContext.Current.Request.MapPath(UploadPath), fileName);
string extension = Path.GetExtension(file.FileName);
//make sure the file is valid
if (!ValidateExtension(extension))
{
imageResult.Success = false;
imageResult.ErrorMessage = "Invalid Extension";
return imageResult;
}
try
{
file.SaveAs(path);
Image imgOriginal = Image.FromFile(path);
//pass in whatever value you want
Image imgActual = Scale(imgOriginal);
imgOriginal.Dispose();
imgActual.Save(path);
imgActual.Dispose();
imageResult.ImageName = fileName;
return imageResult;
}
catch (Exception ex)
{
// you might NOT want to show the exception error for the user
// this is generally logging or testing
imageResult.Success = false;
imageResult.ErrorMessage = ex.Message;
return imageResult;
}
}
// you can also create an Mvc dataannotation to validate the extension of image in both server side and client side
// don't forget to add (.JPG, .JPEG or .PNG on these extension, because you can facing this type of problem
private bool ValidateExtension(string extension)
{
extension = extension.ToLower();
switch (extension)
{
case ".jpg":
return true;
case ".png":
return true;
case ".gif":
return true;
case ".jpeg":
return true;
default:
return false;
}
}
private Image Scale(Image imgPhoto)
{
float sourceWidth = imgPhoto.Width;
float sourceHeight = imgPhoto.Height;
float destHeight = 0;
float destWidth = 0;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
// force resize, might distort image
if (Width != 0 && Height != 0)
{
destWidth = Width;
destHeight = Height;
}
// change size proportially depending on width or height
else if (Height != 0)
{
destWidth = (float)(Height * sourceWidth) / sourceHeight;
destHeight = Height;
}
else
{
destWidth = Width;
destHeight = (float)(sourceHeight * Width / sourceWidth);
}
Bitmap bmPhoto = new Bitmap((int)destWidth, (int)destHeight,
PixelFormat.Format32bppPArgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
//you can also add these properties to improve the quality of saved image
grPhoto.SmoothingMode = SmoothingMode.HighQuality;
grPhoto.CompositingQuality = CompositingQuality.HighQuality;
grPhoto.PixelOffsetMode = PixelOffsetMode.HighQuality;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, (int)destWidth, (int)destHeight),
new Rectangle(sourceX, sourceY, (int)sourceWidth, (int)sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
//you can also create another method to verify if a saved image with similar name exist and use it in som method of controller like (Modify your account
public ImageResult VerifyUploadFile(HttpPostedFileBase file)
{
var fileName = Path.GetFileName(file.FileName);
string finalFileName = UploadPath + fileName;
// si une telle image existe déjà, renvoyer le nom du fichier et dire que le succes est faux
if (System.IO.File.Exists
(HttpContext.Current.Request.MapPath(UploadPath + finalFileName)))
{
//file exists => sucess is false
return new ImageResult { Success = false, ErrorMessage = null, ImageName =finalFileName };
}
//file doesn't exist, upload item but validate first
return RenameUploadFile(file);
}
}
You can use it after in the controller depending of your need
[HttpPost]
public ActionResult Index(FormCollection formCollection)
{
foreach (string item in Request.Files)
{
HttpPostedFileBase file = Request.Files[item] as HttpPostedFileBase;
if (file.ContentLength == 0)
continue;
if (file.ContentLength > 0)
{
// width + height will force size, care for distortion
//Exmaple: ImageUpload imageUpload = new ImageUpload { Width = 800, Height = 700 };
// height will increase the width proportionally
//Example: ImageUpload imageUpload = new ImageUpload { Height= 600 };
// width will increase the height proportionally
ImageUpload imageUpload = new ImageUpload { Width= 600 };
// rename, resize, and upload
//return object that contains {bool Success,string ErrorMessage,string ImageName}
ImageResult imageResult = imageUpload.RenameUploadFile(file);
if (imageResult.Success)
{
//TODO: write the filename to the db
Console.WriteLine(imageResult.ImageName);
}
else
{
// use imageResult.ErrorMessage to show the error
ViewBag.Error = imageResult.ErrorMessage;
}
}
}
return View();
}
You can use verifyupload at your need.
var imagePhysicalPath = #"c://image.jpg";
var newImagePhysicalPath = #"c://new-image.jpg";
var image = new System.Web.Helpers.WebImage(imagePhysicalPath)
.Resize(width + 1, height + 1, false, true)//+1 because webimage use 1px for border
.Crop(1, 1) //remove border
.Save(newImagePhysicalPath);

Xamarin Forms - Resize Camera Picture

Someone helped me get this code for taking a picture using xamarin forms labs camera:
picker = DependencyService.Get<IMediaPicker> ();
task = picker.TakePhotoAsync (new CameraMediaStorageOptions {
DefaultCamera = CameraDevice.Rear,
MaxPixelDimension = 800,
});
img.BackgroundColor = Color.Gray;
Device.StartTimer (TimeSpan.FromMilliseconds (250), () => {
if (task != null) {
if (task.Status == TaskStatus.RanToCompletion) {
Device.BeginInvokeOnMainThread (async () => {
//img.Source = ImageSource.FromStream (() => task.Result.Source);
var fileAccess = Resolver.Resolve<IFileAccess> ();
string imageName = "img_user_" + User.CurrentUser().id + "_" + DateTime.Now.ToString ("yy_MM_dd_HH_mm_ss") + ".jpg";
fileName = imageName;
fileAccess.WriteStream (imageName, task.Result.Source);
fileLocation = fileAccess.FullPath(imageName);
FileStream fileStream = new FileStream(fileAccess.FullPath(imageName), FileMode.Open, System.IO.FileAccess.Read);
imageUrl = (string)test[0]["url"];
img.Source = imageUrl;
});
}
return task.Status != TaskStatus.Canceled
&& task.Status != TaskStatus.Faulted
&& task.Status != TaskStatus.RanToCompletion;
}
return true;
});
It saves the image, but the actual size of the phone picture taken is huge, is there a way to resize it.
UPDATE: The original answer is not useful, see below for updated answer. The issue was the PCL library was very slow and consumed too much memory.
ORIGINAL ANSWER (do not use):
I found an image I/O library, ImageTools-PCL, which I forked on github and trimmed down what wouldn't compile in Xamarin, keeping the modifications to minimum and the result seems to work.
To use it download the linked repository, compile it with Xamarin and add the DLLs from Build folder to your Forms project.
To resize an image you can do this (should fit the context of your question)
var decoder = new ImageTools.IO.Jpeg.JpegDecoder ();
ImageTools.ExtendedImage inImage = new ImageTools.ExtendedImage ();
decoder.Decode (inImage, task.Result.Source);
var outImage = ImageTools.ExtendedImage.Resize (inImage, 1024, new ImageTools.Filtering.BilinearResizer ());
var encoder = new ImageTools.IO.Jpeg.JpegEncoder ();
encoder.Encode (outImage, fileAccess.CreateStream (imageName));
ImageSource imgSource = ImageSource.FromFile (fileAccess.FullPath (imageName));
UPDATED ANSWER:
Get Xamarin.XLabs from nuget, learn about using Resolver, create an IImageService interface with Resize method.
Implementation for iOS:
public class ImageServiceIOS: IImageService{
public void ResizeImage(string sourceFile, string targetFile, float maxWidth, float maxHeight)
{
if (File.Exists(sourceFile) && !File.Exists(targetFile))
{
using (UIImage sourceImage = UIImage.FromFile(sourceFile))
{
var sourceSize = sourceImage.Size;
var maxResizeFactor = Math.Min(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);
if (!Directory.Exists(Path.GetDirectoryName(targetFile)))
Directory.CreateDirectory(Path.GetDirectoryName(targetFile));
if (maxResizeFactor > 0.9)
{
File.Copy(sourceFile, targetFile);
}
else
{
var width = maxResizeFactor * sourceSize.Width;
var height = maxResizeFactor * sourceSize.Height;
UIGraphics.BeginImageContextWithOptions(new CGSize((float)width, (float)height), true, 1.0f);
// UIGraphics.GetCurrentContext().RotateCTM(90 / Math.PI);
sourceImage.Draw(new CGRect(0, 0, (float)width, (float)height));
var resultImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
if (targetFile.ToLower().EndsWith("png"))
resultImage.AsPNG().Save(targetFile, true);
else
resultImage.AsJPEG().Save(targetFile, true);
}
}
}
}
}
Implementation of the service for Android:
public class ImageServiceDroid: IImageService{
public void ResizeImage(string sourceFile, string targetFile, float maxWidth, float maxHeight)
{
if (!File.Exists(targetFile) && File.Exists(sourceFile))
{
// First decode with inJustDecodeBounds=true to check dimensions
var options = new BitmapFactory.Options()
{
InJustDecodeBounds = false,
InPurgeable = true,
};
using (var image = BitmapFactory.DecodeFile(sourceFile, options))
{
if (image != null)
{
var sourceSize = new Size((int)image.GetBitmapInfo().Height, (int)image.GetBitmapInfo().Width);
var maxResizeFactor = Math.Min(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);
string targetDir = System.IO.Path.GetDirectoryName(targetFile);
if (!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
if (maxResizeFactor > 0.9)
{
File.Copy(sourceFile, targetFile);
}
else
{
var width = (int)(maxResizeFactor * sourceSize.Width);
var height = (int)(maxResizeFactor * sourceSize.Height);
using (var bitmapScaled = Bitmap.CreateScaledBitmap(image, height, width, true))
{
using (Stream outStream = File.Create(targetFile))
{
if (targetFile.ToLower().EndsWith("png"))
bitmapScaled.Compress(Bitmap.CompressFormat.Png, 100, outStream);
else
bitmapScaled.Compress(Bitmap.CompressFormat.Jpeg, 95, outStream);
}
bitmapScaled.Recycle();
}
}
image.Recycle();
}
else
Log.E("Image scaling failed: " + sourceFile);
}
}
}
}
#Sten's answer might encounter out-of-memory problem on some android devices. Here's my solution to implement the ResizeImage function
, which is according to google's "Loading Large Bitmaps Efficiently" document:
public void ResizeImage (string sourceFile, string targetFile, int reqWidth, int reqHeight)
{
if (!File.Exists (targetFile) && File.Exists (sourceFile)) {
var downImg = decodeSampledBitmapFromFile (sourceFile, reqWidth, reqHeight);
using (var outStream = File.Create (targetFile)) {
if (targetFile.ToLower ().EndsWith ("png"))
downImg.Compress (Bitmap.CompressFormat.Png, 100, outStream);
else
downImg.Compress (Bitmap.CompressFormat.Jpeg, 95, outStream);
}
downImg.Recycle();
}
}
public static Bitmap decodeSampledBitmapFromFile (string path, int reqWidth, int reqHeight)
{
// First decode with inJustDecodeBounds=true to check dimensions
var options = new BitmapFactory.Options ();
options.InJustDecodeBounds = true;
BitmapFactory.DecodeFile (path, options);
// Calculate inSampleSize
options.InSampleSize = calculateInSampleSize (options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.InJustDecodeBounds = false;
return BitmapFactory.DecodeFile (path, options);
}
public static int calculateInSampleSize (BitmapFactory.Options options, int reqWidth, int reqHeight)
{
// Raw height and width of image
int height = options.OutHeight;
int width = options.OutWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
int halfHeight = height / 2;
int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
You can do this natively for each platform and use an interface. Heres an example for IOS
In your PCL project you need to add an interface
public interface IImageResizer
{
byte[] ResizeImage (byte[] imageData, double width, double height);
}
Then to resize an image in your code, you can load the IOS implementation of that interface using the DependencyService and run the ResizeImage method
var resizer = DependencyService.Get<IImageResizer>();
var resizedBytes = resizer.ResizeImage (originalImageByteArray, 400, 400);
Stream stream = new MemoryStream(resizedBytes);
image.Source = ImageSource.FromStream(stream);
IOS Implementation, add this class to your IOS project.
[assembly: Xamarin.Forms.Dependency (typeof (ImageResizer_iOS))]
namespace YourNamespace
{
public class ImageResizer_iOS : IImageResizer
{
public byte[] ResizeImage (byte[] imageData, double maxWidth, double maxHeight)
{
UIImage originalImage = ImageFromByteArray (imageData);
double width = 300, height = 300;
double maxAspect = (double)maxWidth / (double)maxHeight;
double aspect = (double)originalImage.Size.Width/(double)originalImage.Size.Height;
if (maxAspect > aspect && originalImage.Size.Width > maxWidth) {
//Width is the bigger dimension relative to max bounds
width = maxWidth;
height = maxWidth / aspect;
}else if (maxAspect <= aspect && originalImage.Size.Height > maxHeight){
//Height is the bigger dimension
height = maxHeight;
width = maxHeight * aspect;
}
return originalImage.Scale(new SizeF((float)width,(float)height)).AsJPEG ().ToArray ();
}
public static MonoTouch.UIKit.UIImage ImageFromByteArray(byte[] data)
{
if (data == null) {
return null;
}
MonoTouch.UIKit.UIImage image;
try {
image = new MonoTouch.UIKit.UIImage(MonoTouch.Foundation.NSData.FromArray(data));
} catch (Exception e) {
Console.WriteLine ("Image load failed: " + e.Message);
return null;
}
return image;
}
}
}
An update from the Xamarin Media Plugin allows you to resize the image
https://github.com/jamesmontemagno/MediaPlugin
... barring that, and you need a more generic resize option (say the image comes from a web call, and not the device, then have a look at:
https://github.com/InquisitorJax/Wibci.Xamarin.Images

download generated images automatically multiple times

I am trying to download around 1000 images. For that first I am generating random number, converting this text to image. After this on button click, I am downloading this generated image. This is working fine. Now I want to run this loop for 1000 times so that I can download thousand images. The below code works fine when the loop is running once, but when the loop is running 1000 times, its not working as I am expecting.
Also, I want to change the destination folder where this images should be downloaded. How can I do that?
Below if I change value of variable i to 1000, the output is not what I am expecting
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 0; i < 1; i++)
{
CallBUttonClick();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
var s = GenerateRandomCode();
RandomImage ci = new RandomImage(s.ToString(), 300, 75);
this.Response.Clear();
this.Response.ContentType = "image/jpeg";
Response.AppendHeader("Content-Disposition", "attachment; filename=downloadedFile.JPG");
ci.Image.Save(this.Response.OutputStream, ImageFormat.Jpeg);
ci.Dispose();
}
protected void CallBUttonClick()
{
Button1_Click(Button1, null);
}
private string GenerateRandomCode()
{
Random r = new Random();
string s = "";
for (int j = 0; j < 5; j++)
{
int i = r.Next(3);
int ch;
switch (i)
{
case 1:
ch = r.Next(0, 9);
s = s + ch.ToString();
break;
case 2:
ch = r.Next(65, 90);
s = s + Convert.ToChar(ch).ToString();
break;
case 3:
ch = r.Next(97, 122);
s = s + Convert.ToChar(ch).ToString();
break;
default:
ch = r.Next(97, 122);
s = s + Convert.ToChar(ch).ToString();
break;
}
r.NextDouble();
r.Next(100, 1999);
}
return s;
}
}
Adding RandomImage.cs class file
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System;
public class RandomImage
{
//Default Constructor
public RandomImage() { }
//property
public string Text
{
get { return this.text; }
}
public Bitmap Image
{
get { return this.image; }
}
public int Width
{
get { return this.width; }
}
public int Height
{
get { return this.height; }
}
//Private variable
private string text;
private int width;
private int height;
private Bitmap image;
private Random random = new Random();
//Methods declaration
public RandomImage(string s, int width, int height)
{
this.text = s;
this.SetDimensions(width, height);
this.GenerateImage();
}
public void Dispose()
{
GC.SuppressFinalize(this);
this.Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
this.image.Dispose();
}
private void SetDimensions(int width, int height)
{
if (width <= 0)
throw new ArgumentOutOfRangeException("width", width,
"Argument out of range, must be greater than zero.");
if (height <= 0)
throw new ArgumentOutOfRangeException("height", height,
"Argument out of range, must be greater than zero.");
this.width = width;
this.height = height;
}
private void GenerateImage()
{
Bitmap bmp = new Bitmap(1, 1);
Graphics graphics = Graphics.FromImage(bmp);
Font font = new Font(FontFamily.GenericSansSerif, 28);
SizeF stringSize = graphics.MeasureString(this.text, font);
bmp = new Bitmap(bmp, (int)stringSize.Width+30, (int)stringSize.Height+30);
graphics = Graphics.FromImage(bmp);
graphics.DrawString(this.text, font, Brushes.White, 0, 0);
font.Dispose();
graphics.Flush();
graphics.Dispose();
this.image = bmp;
}
}
Hi you need to save you bitmap file on physcial folder. I have modified you code. Please see below code
private void GenerateImage()
{
Bitmap bmp = new Bitmap(1, 1);
Graphics graphics = Graphics.FromImage(bmp);
Font font = new Font(FontFamily.GenericSansSerif, 28);
SizeF stringSize = graphics.MeasureString(this.text, font);
bmp = new Bitmap(bmp, (int)stringSize.Width + 30, (int)stringSize.Height + 30);
graphics = Graphics.FromImage(bmp);
graphics.DrawString(this.text, font, Brushes.White, 0, 0);
font.Dispose();
graphics.Flush();
graphics.Dispose();
bmp.Save("C:\\" + this.text + ".jpg");
this.image = bmp;
}
I have also removed below code from button click and rested, it is working fine.
//this.Response.Clear();
//this.Response.ContentType = "image/jpeg";
//Response.AppendHeader("Content-Disposition", "attachment; filename=downloadedFile.JPG");
//ci.Image.Save(this.Response.OutputStream, ImageFormat.Jpeg);
//ci.Dispose();
That's not how the ASP.NET Page Life Cycle works. If you use the Response object to serve a download, you can serve ONE file.
You are approaching the problem from the wrong side; you say "I am trying to download around 1000 images". That is a process on the client side, on the browser if you will.
Yet you are trying to solve this on the server side.
You want 1000 downloads, so you have to initiate 1000 downloads from the client, and let the server side, the one Page you're writing for that, live through that 1000 times.
In other words, you cannot "push download" multiple files from the server, you have to request them one by one.

Selenium webdriver C# - Taking full page screenshot

Can anyone help me to take a full page screenshot using Selenium webdriver. I am using c#/Nunit. The current method i am using is not taking the full browser page.
I am using the code below to take the screenshot.
public void TakeScreenShot(IWebDriver webDriver,string testName,string className)
{
string folderName = String.Format("{0}.{1}", className, testName);
// Create Screenshot folder
string createdFolderLocation = CreateFolder(folderName);
// Take the screenshot
Screenshot ss = ((ITakesScreenshot)webDriver).GetScreenshot();
string screenshot = ss.AsBase64EncodedString;
byte[] screenshotAsByteArray = ss.AsByteArray;
// Save the screenshot
ss.SaveAsFile((string.Format("{0}\\{1}",createdFolderLocation,testName + ".Jpeg")), System.Drawing.Imaging.ImageFormat.Jpeg);
ss.ToString();
}
You can use this package https://www.nuget.org/packages/Noksa.WebDriver.ScreenshotsExtensions/
In order to take a screenshot of the entire page, use the VerticalCombineDecorator:
var vcs = new VerticalCombineDecorator(new ScreenshotMaker());
var screen = _driver.TakeScreenshot(vcs);
"Full-page" screenshots are defined by WebDriver to include the entirety of the page displayed in the browser, not the browser chrome (URL bar, toolbar, window resizing handles, and so on). If you don't care about getting the full DOM in your screenshot, you don't need to use WebDriver to get your screenshot. You can use the API of your operating system to handle that instead.
This one I used in our solution:
public byte[] TakeScreenshot()
{
try
{
var getMaxSide = "return Math.max(document.body.scroll{0}, document.body.offset{0}, document.documentElement.client{0}, document.documentElement.scroll{0}, document.documentElement.offset{0})";
var scrollHeight = (Driver as IJavaScriptExecutor).ExecuteScript(string.Format(getMaxSide, "Height"));
var scrollWidth = (Driver as IJavaScriptExecutor).ExecuteScript(string.Format(getMaxSide, "Width"));
Driver.Manage().Window.Size = new Size(int.Parse(scrollWidth.ToString()), int.Parse(scrollHeight.ToString()));
return (Driver as ITakesScreenshot).GetScreenshot().AsByteArray;
}
catch
{
return Array.Empty<byte>();
}
}
Then you can use the result to attach it to e.g. Allure or NUnit test results:
private void AttachScreenshot()
{
var screenshot = _browser?.TakeScreenshot();
if (screenshot.Length > 0)
{
// add screenshot to test results
var path = DateTime.Now.Ticks.ToString() + ".png";
File.WriteAllBytes(path, screenshot);
TestContext.AddTestAttachment(path, "screenshot");
// attach screenshot to Allure report
AllureLifecycle.Instance.AddAttachment("screenshot", "image/png", screenshot);
}
}
Try changing the size of the browser window to something huge before taking your screen shot. I have the size to 10 less than the width, and 10 less than the height. Try adding rather than subtracting.
driver = new FirefoxDriver(firefoxProfile);
if (Config.MAXIMIZE_BROWSER_WINDOW)
{
driver.Manage().Window.Size = new System.Drawing.Size(System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - 10, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - 10);
}
you may try this
IWebDriver driver = new PhantomJSDriver();
driver.Navigate().GoToUrl("http://www.google.com");
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile("image.png", ImageFormat.Png);
Greetings from 2017))!
If the page size is larger than the screen size - you can use the PhantomJS driver (PhantomJS download page)
var fileName = "test.png";
var size = new Size(800, 2000);
var url = "https://stackoverflow.com/";
using (var driver = new PhantomJSDriver())
{
driver.Manage().Window.Size = size;
driver.Navigate().GoToUrl(url);
((ITakesScreenshot)driver)
.GetScreenshot()
.SaveAsFile(fileName, ImageFormat.Png);
driver.Close();
}
I remeber that ((ITakesScreenshot)webDriver).GetScreenshot(); takes full page screenshot but if you have some ajax request and other loading elements you can add scrolling and at the end to wait some seconds, after that you will know that it took full loaded page screenshot.
for (int second = 0;; second++)
{
if (second >= 4)
{
break;
}
((IJavaScriptExecutor)Global.Driver).ExecuteScript("window.scrollBy(0,800)", string.Empty);
Thread.Sleep(500);
}
Thread.Sleep(3000);
Try this hope it will work fine for u.
public void TakeScreenshot(string SSName)
{
try
{
string path = "D:\\WorkSpace\\Screenshot\\";
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
ss.SaveAsFile((path + SSName), System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
Changing browser height doesn't always work. This is the solution I used. It scrolls through the page and composes the full-page screenshot.
public static Image TakeFullPageScreenshot(this RemoteWebDriver driver, int maxHeight = 10000)
{
Bitmap fullPageScreenshot = null;
using (var fullMs = new MemoryStream((driver.GetScreenshot()).AsByteArray)) {
fullPageScreenshot = Image.FromStream(fullMs) as Bitmap;
}
var originalPageOffset = driver.GetPageOffset();
var prevPageOffset = 0;
var currentPageOffset = 0;
var scrollLength = (int)(driver.Manage().Window.Size.Height / 1.5);
while (fullPageScreenshot.Height < maxHeight)
{
prevPageOffset = driver.GetPageOffset().Y;
driver.ScrollPageBy(0, scrollLength);
System.Threading.Thread.Sleep(500);
currentPageOffset = driver.GetPageOffset().Y;
if (prevPageOffset == currentPageOffset)
{
break;
}
var pageMovedBy = currentPageOffset - prevPageOffset;
using (var ms = new MemoryStream(driver.GetScreenshot().AsByteArray))
{
using (var viewPortScreenshot = Image.FromStream(ms) as Bitmap)
{
var croppedScreenshot = CropBitmapAtRect(viewPortScreenshot, new Rectangle(0, viewPortScreenshot.Height - pageMovedBy, viewPortScreenshot.Width, pageMovedBy));
var newFullPage = AppendBitmap(fullPageScreenshot, croppedScreenshot);
fullPageScreenshot.Dispose();
fullPageScreenshot = newFullPage;
}
}
}
driver.ScrollPageTo(originalPageOffset.X, originalPageOffset.Y);
return fullPageScreenshot;
}
public static Bitmap CropBitmapAtRect(Bitmap b, Rectangle r)
{
Bitmap nb = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(nb))
{
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
}
public static Bitmap AppendBitmap(Bitmap source, Bitmap target, int spacing = 0)
{
int w = Math.Max(source.Width, target.Width);
int h = source.Height + target.Height + spacing;
Bitmap bmp = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, 0, 0);
g.DrawImage(target, 0, source.Height + spacing);
}
return bmp;
}
public static void ScrollPageBy(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(window.pageXOffset + arguments[0], window.pageYOffset + arguments[1]);", x, y);
}
public static void ScrollPageTo(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(arguments[0], arguments[1]);", x, y);
}
public static Point GetPageOffset(this RemoteWebDriver driver)
{
var offsetArray = driver.ExecuteScript(#"return [window.pageXOffset, window.pageYOffset];") as ReadOnlyCollection<object>;
var x = (long)offsetArray[0];
var y = (long)offsetArray[1];
return new Point((int)x, (int)y);
}
based on the answer from #Michal Kalous I created an etension class.
This also takes into account the font size currently set in widows and the real viewport size and removes the vertical scrollbar by setting body.style.overflowY to hidden.
Usage
RemoteWebDriver driver = new EdgeDriver();
driver.SetViewportSize(1200, 1200);
driver.Navigate().GoToUrl("https://www.bikereview.info/en/ktm-1290-super-duke-rr-innerhalb-von-48-minuten-ausverkauft.html");
Image tempImage = driver.TakeFullPageScreenshot();
tempImage.Save(#"c:\full.png", ImageFormat.Png);
driver.Close();
driver.Quit();
Extension-Class
using System;
using System.Drawing;
using System.IO;
using OpenQA.Selenium.Remote;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using OpenQA.Selenium;
namespace TestRenderHtmlToPng
{
public static class RemoteWebDriverExtensions
{
public static Image TakeFullPageScreenshot(this RemoteWebDriver driver, int maxHeight = 10000)
{
//Screenshots depend on fontscaleing-property in windows
double DpiScalingFactor = GetDpiScalingFactor();
Bitmap fullPageScreenshot = null;
using (var fullMs = new MemoryStream((driver.GetScreenshotOverflowHidden()).AsByteArray))
{
fullPageScreenshot = Image.FromStream(fullMs) as Bitmap;
}
var originalPageOffset = driver.GetPageOffset();
var prevPageOffset = 0;
var currentPageOffset = 0;
var scrollLength = driver.GetWindowInnerHeight();
while (fullPageScreenshot.Height < maxHeight)
{
prevPageOffset = driver.GetPageOffset().Y;
driver.ScrollPageBy(0, scrollLength);
System.Threading.Thread.Sleep(100);
currentPageOffset = driver.GetPageOffset().Y;
if (prevPageOffset == currentPageOffset)
{
break;
}
var pageMovedBy = currentPageOffset - prevPageOffset;
pageMovedBy = (int)(pageMovedBy * DpiScalingFactor);
using (var ms = new MemoryStream(driver.GetScreenshotOverflowHidden().AsByteArray))
{
Bitmap fullPageScreenshot1 = Image.FromStream(ms) as Bitmap;
using (var viewPortScreenshot = Image.FromStream(ms) as Bitmap)
{
var s = driver.Manage().Window.Size;
var croppedScreenshot = CropBitmapAtRect(viewPortScreenshot, new Rectangle(0, viewPortScreenshot.Height - pageMovedBy, viewPortScreenshot.Width, pageMovedBy));
var newFullPage = AppendBitmap(fullPageScreenshot, croppedScreenshot);
fullPageScreenshot.Dispose();
fullPageScreenshot = newFullPage;
}
}
}
driver.ScrollPageTo(originalPageOffset.X, originalPageOffset.Y);
return fullPageScreenshot;
}
private static Bitmap CropBitmapAtRect(Bitmap b, Rectangle r)
{
Bitmap nb = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(nb))
{
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
}
private static Bitmap AppendBitmap(Bitmap source, Bitmap target, int spacing = 0)
{
int w = Math.Max(source.Width, target.Width);
int h = source.Height + target.Height + spacing;
Bitmap bmp = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, 0, 0);
g.DrawImage(target, 0, source.Height + spacing);
}
return bmp;
}
private static Screenshot GetScreenshotOverflowHidden(this RemoteWebDriver driver)
{
driver.ExecuteScript(#" document.body.style.overflowY = ""hidden"";");
var s = driver.GetScreenshot();
driver.ExecuteScript(#" document.body.style.overflowY = """";");
return s;
}
private static void ScrollPageBy(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(window.pageXOffset + arguments[0], window.pageYOffset + arguments[1]);", x, y);
}
private static void ScrollPageTo(this RemoteWebDriver driver, int x = 0, int y = 0)
{
driver.ExecuteScript(#"window.scroll(arguments[0], arguments[1]);", x, y);
}
public static void SetViewportSize(this RemoteWebDriver driver, int width, int height)
{
var jsGetPadding = #"return [ window.outerWidth - window.innerWidth,window.outerHeight - window.innerHeight ];";
var paddingArray = driver.ExecuteScript(jsGetPadding) as ReadOnlyCollection<object>;
driver.Manage().Window.Size = new Size(width + int.Parse(paddingArray[0].ToString()), height + int.Parse(paddingArray[1].ToString()));
}
private static Point GetPageOffset(this RemoteWebDriver driver)
{
var offsetArray = driver.ExecuteScript(#"return [window.pageXOffset, window.pageYOffset];") as ReadOnlyCollection<object>;
var x = int.Parse(offsetArray[0].ToString());
var y = int.Parse(offsetArray[1].ToString().Split(',')[0]);
return new Point((int)x, (int)y);
}
private static int GetWindowInnerHeight(this RemoteWebDriver driver)
{
var Value = driver.ExecuteScript(#"return [window.innerHeight];") as ReadOnlyCollection<object>;
return int.Parse(Value[0].ToString());
}
[DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
public enum DeviceCap
{
VERTRES = 10,
DESKTOPVERTRES = 117,
// http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
// https://stackoverflow.com/questions/5977445/how-to-get-windows-display-settings#answer-21450169
}
private static float GetDpiScalingFactor()
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr desktop = g.GetHdc();
int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
return ScreenScalingFactor; // 1.25 = 125%
}
}
}

Resources