Re-sizing and saving image to database - c#

I see in my code I'm not passing the re-scaled image into the InputStream, I'm passing in the original file-base. Is it possible to pass in newImage in some way as its of a different type?
I'm using MVC2 .NET 3.5
Here's the controller for uploading:
[HttpPost]
public ActionResult ImageUpload(HttpPostedFileBase fileBase, PhotoViewModel photoViewModel)
{
if (photoViewModel.Button == "Upload")
{
photoViewModel.ImageValid = "Valid";
ImageService imageService = new ImageService();
if (fileBase != null && fileBase.ContentLength > 0 && fileBase.ContentLength <= 2097152 && fileBase.ContentType.Contains("image/"))
{
Path.GetExtension(fileBase.ContentType);
var extension = Path.GetExtension(fileBase.FileName);
if (extension.ToLower() != ".jpg" && extension.ToLower() != ".gif") // only allow these types
{
photoViewModel.ImageValid = "Not Valid";
ModelState.AddModelError("Photo", "Wrong Image Type");
return View(photoViewModel);
}
EncoderParameters encodingParameters = new EncoderParameters(1);
encodingParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L); // Set the JPG Quality percentage
ImageCodecInfo jpgEncoder = imageService.GetEncoderInfo("image/jpeg");
var uploadedimage = Image.FromStream(fileBase.InputStream, true, true);
Bitmap originalImage = new Bitmap(uploadedimage);
Bitmap newImage = new Bitmap(originalImage, 274, 354);
Graphics g = Graphics.FromImage(newImage);
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
var streamLarge = new MemoryStream();
newImage.Save(streamLarge, jpgEncoder, encodingParameters);
var fileExtension = Path.GetExtension(extension);
string newname;
if (photoViewModel.photoURL != null)
{
newname = photoViewModel.photoURL;
}
else
{
newname = Guid.NewGuid() + fileExtension;
}
//changed this up now, so it stores the image in db as apposed to physical path
photoViewModel.photo = newname;
photoViewModel.ContentType = fileBase.ContentType;
Int32 length = fileBase.ContentLength;
byte[] tempImage = new byte[length];
fileBase.InputStream.Read(tempImage, 0, length);
photoViewModel.ImageData = tempImage;
TempImageUpload tempImageUpload = new TempImageUpload();
tempImageUpload.TempImageData = tempImage;
tempImageUpload.ContentType = photoViewModel.ContentType;
photoViewModel.TempImageId = _service.InsertImageDataBlob(tempImageUpload);
originalImage.Dispose();
streamLarge.Dispose();
return View(photoViewModel);
}
if (fileBase != null)
{
if (fileBase.ContentLength > 0) ModelState.AddModelError("Photo", "Image size too small");
if (fileBase.ContentLength <= 2097152) ModelState.AddModelError("Photo", "Image size too big");
if (fileBase.ContentType.Contains("image/")) ModelState.AddModelError("Photo", "Wrong Image Type");
}
else ModelState.AddModelError("Photo", "Please upload a image");
if (!ModelState.IsValid)
{
photoViewModel.ImageValid = "Not Valid";
return View(photoViewModel);
}
}
return View(photoViewModel);
}
Here's my repository class:
public int InsertImageDataBlob(TempImageUpload tempImageUpload)
{
int ReturnedPhotoId;
try
{
var phototempdata = new Photo
{
ImageData = tempImageUpload.TempImageData,
contentType = tempImageUpload.ContentType,
dateUploaded = DateTime.Now
};
_db.Photos.InsertOnSubmit(phototempdata);
Save();
ReturnedPhotoId = phototempdata.id;
return ReturnedPhotoId;
}
catch (Exception ex)
{
//ErrorLogging;
}
return 0;
}
And image data field (image type) in the database gets populated with data.

probably it works..or not :-P ....my changes in your code for the bypassing/rescaling issue (check my comments in your code):
[HttpPost]
public ActionResult ImageUpload(HttpPostedFileBase fileBase, PhotoViewModel photoViewModel)
{
if (photoViewModel.Button == "Upload")
{
photoViewModel.ImageValid = "Valid";
ImageService imageService = new ImageService();
if (fileBase != null && fileBase.ContentLength > 0 && fileBase.ContentLength <= 2097152 && fileBase.ContentType.Contains("image/"))
{
Path.GetExtension(fileBase.ContentType);
var extension = Path.GetExtension(fileBase.FileName);
if (extension.ToLower() != ".jpg" && extension.ToLower() != ".gif") // only allow these types
{
photoViewModel.ImageValid = "Not Valid";
ModelState.AddModelError("Photo", "Wrong Image Type");
return View(photoViewModel);
}
EncoderParameters encodingParameters = new EncoderParameters(1);
encodingParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L); // Set the JPG Quality percentage
ImageCodecInfo jpgEncoder = imageService.GetEncoderInfo("image/jpeg");
var uploadedimage = Image.FromStream(fileBase.InputStream, true, true);
Bitmap originalImage = new Bitmap(uploadedimage);
Bitmap newImage = new Bitmap(originalImage, 274, 354);
Graphics g = Graphics.FromImage(newImage);
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
// change from originalImage to newImage
g.DrawImage(newImage, 0, 0, newImage.Width, newImage.Height);
var streamLarge = new MemoryStream();
newImage.Save(streamLarge, jpgEncoder, encodingParameters);
var fileExtension = Path.GetExtension(extension);
string newname;
if (photoViewModel.photoURL != null)
{
newname = photoViewModel.photoURL;
}
else
{
newname = Guid.NewGuid() + fileExtension;
}
//changed this up now, so it stores the image in db as apposed to physical path
photoViewModel.photo = newname;
photoViewModel.ContentType = fileBase.ContentType;
// using the memoryStream streamLarge
// old code: Int32 length = fileBase.ContentLength;
byte[] tempImage = new byte[streamLarge.Length];
// replace fileBase.InputStream with streamLarge
streamLarge.Read(tempImage, 0, length);
photoViewModel.ImageData = tempImage;
TempImageUpload tempImageUpload = new TempImageUpload();
tempImageUpload.TempImageData = tempImage;
tempImageUpload.ContentType = photoViewModel.ContentType;
photoViewModel.TempImageId = _service.InsertImageDataBlob(tempImageUpload);
originalImage.Dispose();
streamLarge.Dispose();
return View(photoViewModel);
}
if (fileBase != null)
{
if (fileBase.ContentLength > 0) ModelState.AddModelError("Photo", "Image size too small");
if (fileBase.ContentLength <= 2097152) ModelState.AddModelError("Photo", "Image size too big");
if (fileBase.ContentType.Contains("image/")) ModelState.AddModelError("Photo", "Wrong Image Type");
}
else ModelState.AddModelError("Photo", "Please upload a image");
if (!ModelState.IsValid)
{
photoViewModel.ImageValid = "Not Valid";
return View(photoViewModel);
}
}
return View(photoViewModel);
}

I actually got it to work with this code:
photoViewModel.photo = newname;
photoViewModel.ContentType = fileBase.ContentType;
streamLarge.Position = 0;
byte[] tempImage = new byte[streamLarge.Length + 1];
streamLarge.Read(tempImage, 0, tempImage.Length);
photoViewModel.ImageData = tempImage;

Related

How to choose multiple image from Gallery at one time (tickbox) in Xamarin Android?

Hi have a Xamarin Android project using C#. Currently I am using await CrossMedia.Current.PickPhotoAsync() method to upload image. However, it did not provide a tickbox beside the images for me to select multiple. How can I manage to select multiple images and upload together?
You could implement it by yourself.
1.Add these methods to your MainActivity.cs file
public static int OPENGALLERYCODE = 100;
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
//If we are calling multiple image selection, enter into here and return photos and their filepaths.
if (requestCode == OPENGALLERYCODE && resultCode == Result.Ok)
{
List<string> images = new List<string>();
if (data != null)
{
//Separate all photos and get the path from them all individually.
ClipData clipData = data.ClipData;
if (clipData != null)
{
for (int i = 0; i < clipData.ItemCount; i++)
{
ClipData.Item item = clipData.GetItemAt(i);
Android.Net.Uri uri = item.Uri;
var path = GetRealPathFromURI(uri);
if (path != null)
{
images.Add(path);
}
}
}
else
{
Android.Net.Uri uri = data.Data;
var path = GetRealPathFromURI(uri);
if (path != null)
{
images.Add(path);
}
}
}
}
}
/// <summary>
/// Get the real path for the current image passed.
/// </summary>
public String GetRealPathFromURI(Android.Net.Uri contentURI)
{
try
{
ICursor imageCursor = null;
string fullPathToImage = "";
imageCursor = ContentResolver.Query(contentURI, null, null, null, null);
imageCursor.MoveToFirst();
int idx = imageCursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);
if (idx != -1)
{
fullPathToImage = imageCursor.GetString(idx);
}
else
{
ICursor cursor = null;
var docID = DocumentsContract.GetDocumentId(contentURI);
var id = docID.Split(':')[1];
var whereSelect = MediaStore.Images.ImageColumns.Id + "=?";
var projections = new string[] { MediaStore.Images.ImageColumns.Data };
cursor = ContentResolver.Query(MediaStore.Images.Media.InternalContentUri, projections, whereSelect, new string[] { id }, null);
if (cursor.Count == 0)
{
cursor = ContentResolver.Query(MediaStore.Images.Media.ExternalContentUri, projections, whereSelect, new string[] { id }, null);
}
var colData = cursor.GetColumnIndexOrThrow(MediaStore.Images.ImageColumns.Data);
cursor.MoveToFirst();
fullPathToImage = cursor.GetString(colData);
}
return fullPathToImage;
}
catch (Exception ex)
{
Toast.MakeText(Xamarin.Forms.Forms.Context, "Unable to get path", ToastLength.Long).Show();
}
return null;
}
2.invoked the following in the specific Activity which you want to open the picker
public void OpenGallery()
{
try
{
var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType("image/*");
imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
imageIntent.SetAction(Intent.ActionGetContent);
this.StartActivityForResult(Intent.CreateChooser(imageIntent, "Select photo"), OPENGALLERYCODE);
Toast.MakeText(this, "Tap and hold to select multiple photos.", ToastLength.Short).Show();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Toast.MakeText(this, "Error. Can not continue, try again.", ToastLength.Long).Show();
}
}
void ClearFileDirectory()
{
var directory = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), ImageHelpers.collectionName).Path.ToString();
if (Directory.Exists(directory))
{
var list = Directory.GetFiles(directory, "*");
if (list.Length > 0)
{
for (int i = 0; i < list.Length; i++)
{
File.Delete(list[i]);
}
}
}
}
//collectionName is the name of the folder in your Android Pictures directory.
public static readonly string collectionName = "TmpPictures";
public string SaveFile(byte[] imageByte, string fileName)
{
var fileDir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), collectionName);
if (!fileDir.Exists())
{
fileDir.Mkdirs();
}
var file = new Java.IO.File(fileDir, fileName);
System.IO.File.WriteAllBytes(file.Path, imageByte);
return file.Path;
}
public string CompressImage(string path)
{
byte[] imageBytes;
//Get the bitmap.
var originalImage = BitmapFactory.DecodeFile(path);
//Set imageSize and imageCompression parameters.
var imageSize = .86;
var imageCompression = 67;
//Resize it and then compress it to Jpeg.
var width = (originalImage.Width * imageSize);
var height = (originalImage.Height * imageSize);
var scaledImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, true);
using (MemoryStream ms = new MemoryStream())
{
scaledImage.Compress(Bitmap.CompressFormat.Jpeg, imageCompression, ms);
imageBytes = ms.ToArray();
}
originalImage.Recycle();
originalImage.Dispose();
GC.Collect();
return SaveFile(imageBytes, Guid.NewGuid().ToString());
}

read images from scanned documents PDFs

I am using itextsharp for extracting content from PDF using c# as follow
public static string GetTextFromAllPages(String pdfPath)
{
PdfReader reader = new PdfReader(pdfPath);
StringWriter output = new StringWriter();
for (int i = 1; i <= reader.NumberOfPages; i++)
output.WriteLine(PdfTextExtractor.GetTextFromPage(reader, i, new SimpleTextExtractionStrategy()));
return output.ToString();
}
Now change I want in this code whenever there are images in PDF it should include an image tag (<img>) in the content.
I tried with the extracting images alone and I am able to do it but not sure how to merge these two codes together to make extracted content consist with img tag also .
Extraction code of image as follow :
private static List<System.Drawing.Image> ExtractImages(String PDFSourcePath)
{
//string res = GetTextFromAllPages(PDFSourcePath);
//File.WriteAllText(#"d:\blobfile\blobfileresult.txt", res);
List<System.Drawing.Image> ImgList = new List<System.Drawing.Image>();
iTextSharp.text.pdf.RandomAccessFileOrArray RAFObj = null;
iTextSharp.text.pdf.PdfReader PDFReaderObj = null;
iTextSharp.text.pdf.PdfObject PDFObj = null;
iTextSharp.text.pdf.PdfStream PDFStremObj = null;
try
{
RAFObj = new iTextSharp.text.pdf.RandomAccessFileOrArray(PDFSourcePath);
PDFReaderObj = new iTextSharp.text.pdf.PdfReader(RAFObj, null);
if (PDFReaderObj.IsOpenedWithFullPermissions)
{
Console.WriteLine("this is a test");
}
for (int i = 0; i <= PDFReaderObj.XrefSize - 1; i++)
{
PDFObj = PDFReaderObj.GetPdfObject(i);
if ((PDFObj != null) && PDFObj.IsStream())
{
PDFStremObj = (iTextSharp.text.pdf.PdfStream)PDFObj;
iTextSharp.text.pdf.PdfObject subtype = PDFStremObj.Get(iTextSharp.text.pdf.PdfName.SUBTYPE);
if ((subtype != null) && subtype.ToString() == iTextSharp.text.pdf.PdfName.IMAGE.ToString())
// if ((subtype != null) && subtype.ToString() == iTextSharp.text.pdf.PdfName.CCITTFAXDECODE.ToString())
{
byte[] bytes = iTextSharp.text.pdf.PdfReader.GetStreamBytesRaw((iTextSharp.text.pdf.PRStream)PDFStremObj);
if ((bytes != null))
{
try
{
System.IO.MemoryStream MS = new System.IO.MemoryStream(bytes);
MS.Position = 0;
System.Drawing.Image ImgPDF = System.Drawing.Image.FromStream(MS);
ImgList.Add(ImgPDF);
}
catch (Exception e)
{
Console.WriteLine("Exception in extract: " + e);
}
}
}
}
}
PDFReaderObj.Close();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return ImgList;
}

Uploaded images do not get inserted in database

if (imgUpload.HasFiles)
{
try
{
foreach (HttpPostedFile file in imgUpload.PostedFiles)
{
using (Stream fs = file.InputStream)
{
string fileType = file.ContentType;
if (fileType == "image/jpeg" || fileType == "image/jpg" || fileType == "image/gif" || fileType == "image/png" || fileType == "image/bmp")
{
int fileSize = file.ContentLength;
if (fileSize <= 10485760) //Max Size: 10MB
{
Session["imgUpload"] = imgUpload;
err = true;
}
else
{
lblStatus.Text = "<b style='color:red'>Please select a file of max size 2MB only.</b>";
err = false;
}
}
else
{
lblStatus.Text = "<b style='color:red'>Please select an image file only (Ex:*.jpg/*.jpeg/*.gif/*.png/*.bmp)</b>";
err = false;
}
}
}
}
catch (Exception)
{
lblStatus.Text = "<b style='color:red'>Some problem occurred while uploading the file. Please try after some time.</b>";
err = false;
}
}
protected void imgUpload2()
{
objImage = new ImageModel();
objOperation = new Operations();
if (Session["imgUpload"] != null && (!imgUpload.HasFile))
{
imgUpload = (FileUpload)Session["imgUpload"];
}
//else if (imgUpload.HasFile)
//{
// Session["FileUpload1"] = imgUpload;
//}
if (imgUpload.PostedFiles.Count > 0)
{
foreach (HttpPostedFile file in imgUpload.PostedFiles)
{
using (Stream fs = file.InputStream)
{
lblStatus.Visible = false;
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
objImage.ImageName = file.FileName;
objImage.ImageInByte = bytes;
var rs = objOperation.insertImage(objImage);
}
}
}
}
}
public int insertImage(ImageModel objImage)
{
var result = MySqlHelper.ExecuteNonQuery(Common.GetConnection(), CommandType.StoredProcedure, ConstantFields.StoredProcedureClass.sp_insertImage,
new MySqlParameter("image_name",objImage.ImageName),
new MySqlParameter("image_byteImage", objImage.ImageInByte)
);
return result;
}
Stored Procedure:
BEGIN
set #ad_id:=(select max(ad_id) from postadverties p,user_register u
where p.ad_userid=u.user_id);
insert into images(image_name,image_byteImage,image_adid)
values(image_name,image_byteImage,#ad_id);
END
Above is my code to insert the images in database.I have called the imgUpload2() on button click.Issue is when i am trying to insert images the names of images gets inserted but longblob field in database table shows 0 bytes.So please help to find out what is the real issue.
Thank's in advance.

Colour appears faded in corrected CMYK image

I am compressing a pdf containing a number of images. The below code I got while browsing for the PDF compression. It works fine for RBG format images but in case of CMYK format the images appears with inverted colours (as a negative). Somehow I was able to convert the inverted colours but the image colour got faded.
Please suggest how should I proceed. Thanks in advance.
{
PdfReader.unethicalreading = true;
string pdfFile = #"C:\TestPdf.pdf";
PdfReader reader = new PdfReader(pdfFile);
long quality = 50L;
int n = reader.XrefSize;
for (int i = 0; i < n; i++)
{
PdfObject obj = reader.GetPdfObject(i);
if (obj == null || !obj.IsStream()) { continue; }
PdfDictionary dict = (PdfDictionary)PdfReader.GetPdfObject(obj);
PdfObject pdfcolorspace = dict.Get(PdfName.COLORSPACE);
PdfName subType = (PdfName)PdfReader.GetPdfObject(dict.Get(PdfName.SUBTYPE));
if (!PdfName.IMAGE.Equals(subType)) { continue; }
PRStream stream = (PRStream)obj;
try
{
PdfImageObject image = new PdfImageObject(stream);
PdfName filter = (PdfName)image.Get(PdfName.FILTER);
if ( PdfName.JBIG2DECODE.Equals(filter) || PdfName.JPXDECODE.Equals(filter) || PdfName.CCITTFAXDECODE.Equals(filter) || PdfName.FLATEDECODE.Equals(filter))
continue;
System.Drawing.Image img = image.GetDrawingImage();
if (img == null) continue;
var ll = image.GetImageBytesType();
int width = img.Width;
int height = img.Height;
using (System.Drawing.Bitmap dotnetImg = new System.Drawing.Bitmap(img))
{
System.Drawing.Imaging.ImageCodecInfo codec = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[1];
System.Drawing.Imaging.EncoderParameters eParams = new System.Drawing.Imaging.EncoderParameters(1);
eParams.Param[0] = new System.Drawing.Imaging.EncoderParameter( System.Drawing.Imaging.Encoder.Quality, quality);
using (MemoryStream msImg = new MemoryStream())
{
dotnetImg.Save(msImg, codec, eParams);
msImg.Position = 0;
stream.Clear();
if (pdfcolorspace == PdfName.DEVICECMYK)
{
img.Save(msImg, ImageFormat.Jpeg);
stream.Put(PdfName.COLORSPACE, PdfName.DEVICECMYK);
}
else
{
stream.Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
}
stream.SetData( msImg.ToArray(), true, PdfStream.BEST_COMPRESSION);
stream.Put(PdfName.TYPE, PdfName.XOBJECT);
stream.Put(PdfName.SUBTYPE, PdfName.IMAGE);
stream.Put(PdfName.FILTER, PdfName.DCTDECODE);
stream.Put(PdfName.WIDTH, new PdfNumber(width));
stream.Put(PdfName.HEIGHT, new PdfNumber(height));
stream.Put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
}
}
}
catch (Exception ex)
{
}
finally
{
reader.RemoveUnusedObjects();
}
}
PdfStamper stamper = new PdfStamper(reader, new FileStream(#"C:\Compress.pdf", FileMode.Create), PdfWriter.VERSION_1_5);
stamper.FormFlattening = false;
stamper.SetFullCompression();
stamper.Close();
reader.Close();
}

WatiN security exception solution?

I am using Watin to copy a image to the clipboard, I am getting this error when I do so,
is there a work around to this using AlertDialogHandler?
public System.Drawing.Image GetPicture(WatiN.Core.Image image, ref IE browser)
{
if (image == null || !image.Exists || string.IsNullOrEmpty(image.Src))
return null;
const string t_js =
#"var div = document.images[{0}];
div.contentEditable ='true';
var controlRange;
if(document.body.createControlRange)
{{
controlRange = document.body.createControlRange();
controlRange.addElement(div);
controlRange.execCommand('Copy');
}}
div.contentEditable = 'false';";
var cnt = -1;
foreach (var image1 in browser.Images)
{
cnt++;
if (image1 != null && image1.Exists && !string.IsNullOrEmpty(image1.Src) && image1.Src.ToLower() == image.Src.ToLower())
break;
}
var script = string.Format(t_js, cnt);
WatiN.Core.DialogHandlers.AlertDialogHandler alertDialogHandler = new WatiN.Core.DialogHandlers.AlertDialogHandler ();
using (new WatiN.Core.DialogHandlers.UseDialogOnce(browser.DialogWatcher, alertDialogHandler ))
{
browser.RunScript(script); // Exception comes here !!
alertDialogHandler.WaitUntilExists();
alertDialogHandler.OKButton.Click();
browser.WaitForComplete();
}
var data = Clipboard.GetDataObject();
if (data == null)
return null;
var q = data.GetFormats();
q.ToString();
var q2 = data.GetFormats(true);
q2.ToString();
if (data.GetDataPresent(DataFormats.Bitmap))
{
var img = data.GetData(DataFormats.Bitmap, true);
return img as System.Drawing.Image;
}
if (data.GetDataPresent(DataFormats.Dib))
{
var img = data.GetData(DataFormats.Dib, true);
return img as System.Drawing.Image;
}
if (data.GetDataPresent(DataFormats.EnhancedMetafile))
{
var img = data.GetData(DataFormats.EnhancedMetafile, true);
return img as System.Drawing.Image;
}
if (data.GetDataPresent(DataFormats.MetafilePict))
{
var img = data.GetData(DataFormats.MetafilePict, true);
return img as System.Drawing.Image;
}
if (data.GetDataPresent(DataFormats.Tiff))
{
var img = data.GetData(DataFormats.Tiff, true);
return img as System.Drawing.Image;
}
if (data.GetDataPresent(DataFormats.Serializable))
{
var img = data.GetData(DataFormats.Serializable, true);
return img as System.Drawing.Image;
}
return null;
}
Thanks!
image of the security exception:
I believe it has to do something with IE Security settings
Goto
Security Tab -> Select proper zone (Internet/Local/etc) -> Click on Custome Level button -> Enable (Scripting - > Allow programmatic clipboard access)

Categories

Resources