ASP.NET Core Image Resize - asp.net

I'm trying to resize imagine with System.Drawing but im taking that file as IFormFile and when i use the System.Drawing its just keep warning me to about that : cannot implicitly convert type 'System.Drawing.Bitmap' to 'Microsoft.AspNetCore.Http.IFormFile' . I need to resize those photos and save them as IFormFile but i dont know how to do that.
public Task<IFormFile> ResizeImagine300x300(IFormFile file)
{
Image image = Image.FromStream(file.OpenReadStream(), true, true);
var newImage = new Bitmap(1024, 768);
using (var g = Graphics.FromImage(newImage))
{
g.DrawImage(image, 0, 0, 1024, 768);
};
return newImage;//the point where i get the error
}
Is it possible to do it in my way?
If its not possible, then which way i should follow?
Thanks for any suggestion
Edit: I wanna return as a IFormFile because i have a method which is uploading those files to my database. here is my method :
public async Task<FileRepo> FileUploadToDatabase(List<IFormFile> files)
{
foreach (var file in files)
{
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
var fileExtension = Path.GetExtension(file.FileName);
_fileRepo = new FileRepo
{
FileName = fileName,
FileExtension = fileExtension,
FileType = file.ContentType,
CreatedDate= DateTime.Now
};
using (var dataStream = new MemoryStream())
{
await file.CopyToAsync(dataStream);
_fileRepo.FileData = dataStream.ToArray();
}
}
return _fileRepo;
}
After that I'm uploading that _fileRepo variable to my database like that :
var File = _fileUploader.FileUploadToDatabase(files);
var FileResult = File.Result;
FileResult.ProductID = ProductID;
_unitOfWorkFR.RepositoryFileRepo.Create(FileResult);

Related

How to Read barcode image in Xamarin forms

I am trying to read the text from a QRcode image on my mobile app. I am using Xamarin.Forms with ZXing NuGet package.
I have been able to get the file using Xamarin.Essentials FilePicker. But I don't know how to actually read the barcode. I have looked at some stackoverflow solutions and they all seem to be Xamarin.Android based (using BinaryBitmap objects). I need a solution that can work for iOS and UWP as well. Here is what I have so far:
string file = "";
var filePickerOptions = new PickOptions
{
PickerTitle = "Select Barcode Image",
FileTypes = FilePickerFileType.Images
};
var result = await FilePicker.PickAsync(filePickerOptions);
if (result != null)
{
file = result.FullPath;
var res = Decode(file, BarcodeFormat.QR_CODE);
Console.WriteLine(res.Text);
}
public Result Decode(string file, BarcodeFormat? format = null, KeyValuePair<DecodeHintType, object>[] aditionalHints = null)
{
var r = GetReader(format, aditionalHints);
/* I need some function here that will allow me to get the BinaryBitmap from the image file path or something along those lines.*/
var image = GetBinaryBitmap(file);
var result = r.decode(image);
return result;
}
MultiFormatReader GetReader(BarcodeFormat? format, KeyValuePair<DecodeHintType, object>[] aditionalHints)
{
var reader = new MultiFormatReader();
var hints = new Dictionary<DecodeHintType, object>();
if (format.HasValue)
{
hints.Add(DecodeHintType.POSSIBLE_FORMATS, new List<BarcodeFormat>() { format.Value });
}
if (aditionalHints != null)
{
foreach (var ah in aditionalHints)
{
hints.Add(ah.Key, ah.Value);
}
}
reader.Hints = hints;
return reader;
}
https://github.com/Redth/ZXing.Net.Mobile/issues/981. This thread solved it for me. Credit to #jason for this response.

ClosedXML how to freeze rows and columns when i export file

I have implemented the code below, all headers and data are added without any problem. If he wants to block the possibility of editing individual fields or columns in the excel file that is downloaded by the user, then there is a problem, because nothing is blocked
i use for freeze columns/rows, but when i export file and i open file i can edit any fields
worksheet.SheetView.Freeze(1,3);
[HttpGet]
public IActionResult ExportAsExcel()
{
IEnumerable<Employee> employees = this.repo.GetAll<Employee>();
List<EmployeeDTO> employeeDTO = this._mapper.Map<List<EmployeeDTO>>(employees);
using (var workbook = new XLWorkbook())
{
var woorksheet = workbook.Worksheets.Add("Sheet1");
var currentRow = 1;
woorksheet.Cell(currentRow, 1).Value = "ID";
woorksheet.Cell(currentRow, 2).Value = "name";
foreach (var empDtos in employeeDTO)
{
currentRow++;
woorksheet.Cell(currentRow, 1).Value = empDtos.EmployeeId;
woorksheet.Cell(currentRow, 2).Value = empDtos.Name;
}
using (var stream = new MemoryStream())
{
workbook.SaveAs(stream);
var content = stream.ToArray();
return File(
content,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Employee.xlsx"
);
}
}
}

Passing images from one page to another in Xamarin Forms

In my app I need to pass images from one page to another page image view to display. I am taking a photo from camera and do some stuffs, then I want to send that images to the second page.
if (await isCamAvailable())
{
MediaFile photo1 = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions() { Directory = "NewBusiness", Name = "image1.jpg", PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 1024, CompressionQuality = 95 });
if (photo1 != null)
{
PhotoImage1.Source = ImageSource.FromStream(() => { return photo1.GetStream(); });
countList.Remove("a");
countList.Add("a");
}
}
Then I am added it to a string array by doing
private List<string> sendImgList = new List<string>();
sendImgList.Add(createImgByteString(photo1.GetStream()));
private string createImgByteString(Stream data)
{
var bytes = new byte[data.Length];
return Convert.ToBase64String(bytes);
}
Then from second page (for testing i just added only one image)
foreach (string ss in imgList) {
byte[] Base64Stream = Convert.FromBase64String(ss);
imgView.Source = ImageSource.FromStream(() => new MemoryStream(Base64Stream));
}
I followed this example. But image not showing.
https://forums.xamarin.com/discussion/139360/how-to-transfer-images-from-one-page-to-another
Also getting this in logcat..
[0:] ImageLoaderSourceHandler: Image data was invalid: Xamarin.Forms.StreamImageSource05-29 14:22:43.758 W/monodroid-assembly( 8737): typemap: unable to find mapping to a Java type from managed type 'System.Byte, mscorlib'
It seems that you used the Media.Plugin . Why don't you pass the ImageSource directly?
If you do want to convert it to byte array , check the following code
public byte[] GetImageStreamAsBytes(Stream input)
{
var 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();
}
}
var imgDate = GetImageStreamAsBytes(photo1.GetStream());
It would be better to pass the byte array directly .
The best mode to pass parameter in pages is with Prism.
https://prismlibrary.com/docs/xamarin-forms/navigation/passing-parameters.html
>
_navigationService.NavigateAsync(new Uri("MainPage", new NavigationParameters
{
{ "key_parameter", image }
})));
And on other page:
>
public override void OnNavigatedTo(INavigationParameters parameters)
{
image = (Image)parameters["key_parameter"];
}

Making screen capture in xamarin.forms

Is there a package that does screen capture in xamarin.forms ?
I need also to capture google maps screen shots
Check out this blog post by Daniel Hindrikes.
I'm going to assume that you use a PCL for your shared code.
You will need to create an interface in your PCL. He calls it IScreenshotManager. The declaration looks like this:
public interface IScreenshotManager
{
Task<byte[]> CaptureAsync();
}
Now all platforms will have their own implementation for it.
For iOS;
public class ScreenshotManager : IScreenshotManager
{
public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
{
var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
using(var imageData = image.AsPNG())
{
var bytes = new byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
return bytes;
}
}
}
For Android:
public class ScreenshotManager : IScreenshotManager
{
public static Activity Activity { get; set; }
public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
{
if(Activity == null)
{
throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
}
var view = Activity.Window.DecorView;
view.DrawingCacheEnabled = true;
Bitmap bitmap = view.GetDrawingCache(true);
byte[] bitmapData;
using (var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
return bitmapData;
}
}
And for Windows Phone:
public class ScreenshotManager : IScreenshotManager
{
public async Task<byte[]> CaptureAsync()
{
var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
var screenImage = new WriteableBitmap((int)rootFrame.ActualWidth, (int)rootFrame.ActualHeight);
screenImage.Render(rootFrame, new MatrixTransform());
screenImage.Invalidate();
using (var stream = new MemoryStream())
{
screenImage.SaveJpeg(stream, screenImage.PixelWidth, screenImage.PixelHeight, 0, 100);
var bytes = stream.ToArray();
return bytes;
}
}
}
Don't forget to register your platform specific implementations with the attribute which registers it with the Dependency Service, like this:
[assembly: Xamarin.Forms.Dependency (typeof (ScreenshotManager))]
It goes above the namespace declaration.
Now from your shared code you would be able to get the byte[] of a screenshot with a call like this:
var screenshotBytes = DependencyService.Get<IScreenshotManager>().CaptureAsync();
You probably want to check if DependencyService.Get<IScreenshotManager>() isn't null before using it.
After that you can turn your byte[] into an image and do whatever you like with it!
Implementation for UWP
public async Task<byte[]> CaptureAsync()
{
//create and capture Window
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(Window.Current.Content);
var pixelpuffer = await renderTargetBitmap.GetPixelsAsync();
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
IRandomAccessStream stream = new InMemoryRandomAccessStream();
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, logicalDpi, logicalDpi, pixelpuffer.ToArray());
await encoder.FlushAsync();
byte[] resultingBuffer = new byte[stream.Size];
await stream.ReadAsync(resultingBuffer.AsBuffer(), (uint)resultingBuffer.Length, InputStreamOptions.None);
return resultingBuffer;
}

How to make return the result of (need to bind image to view) webapi to getjson?

I am working on webapi. I had optimized the images and saving in folder here. I had uploaded images into one folder before uploading in to the destination folder.
I am optimizing a single image in to 3 different sizes (large, thumbnail, medium) but image sizes are saved in one folder, now I need to make return those images to view page and bind to view page. How can I do that? I am new to webapi.
Here my controllers
public Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var uploadFolder = HostingEnvironment.MapPath("~/App_Sprites/UploadFolder");
uploadFolder = Path.Combine(uploadFolder, DateTime.Now.ToString("yyyyMMddhhmmssfff"));
Directory.CreateDirectory(uploadFolder);
var streamProvider = new PreserveFilenameMultipartFileStreamProvider(uploadFolder);
return Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
{
foreach (var uploadedFile in Directory.GetFiles(uploadFolder))
{
var thumbnail = Path.Combine(uploadFolder, "thumb-" + Path.GetFileName(uploadedFile));
var medium = Path.Combine(uploadFolder, "medium-" + Path.GetFileName(uploadedFile));
var large = Path.Combine(uploadFolder, "large-" + Path.GetFileName(uploadedFile));
ImageTools.Resize(uploadedFile, thumbnail, 80, 80);
ImageTools.Resize(uploadedFile, medium, 48, 48);
ImageTools.Resize(uploadedFile, large, 128, 128);
}
return Request.CreateResponse(HttpStatusCode.Accepted);
});
}
}
and my class file
public class ImageTools
{
public static void Resize(string original, string output, int width, int height)
{
using (var image = Image.FromFile(original))
using (var thumbnail = new Bitmap(width, height))
using (var graphics = Graphics.FromImage(thumbnail))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.DrawImage(image, 0, 0, width, height);
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
thumbnail.Save(output, info[1], encoderParameters);
}
}
}
and class file for save
public class PreserveFilenameMultipartFileStreamProvider : MultipartFileStreamProvider
{
public PreserveFilenameMultipartFileStreamProvider(string rootPath)
: base(rootPath)
{
}
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", "");
}
}
finally my layout page
#using (Html.BeginRouteForm("DefaultApi", new { httproute = "", controller = "Upload" }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="image" multiple="multiple" accept="image/*" />
<button type="submit">Upload</button>
}
Here I had the images in folder now I need to save those images as well. I need bind those in my layout page how could I do that?
as of above question i have example sight that helps more follow and look for as above question to implement the coding for your implement
http://www.codeproject.com/Articles/379980/Fancy-ASP-NET-MVC-Image-Uploader?msg=4389108#xx4389108xx
as of above question no problem i think it is increasing with quality option you just have to do simple just decrease the quality make upload image and check it once
public static void Resize(string original, string output, int width, int height)
{
using (var image = Image.FromFile(original))
using (var thumbnail = new Bitmap(width, height))
using (var graphics = Graphics.FromImage(thumbnail))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.DrawImage(image, 0, 0, width, height);
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 80L);
thumbnail.Save(output, info[1], encoderParameters);
}
}

Resources