Resizing Awesomium WebView does not resize surface - c#

I'm using awesomium to take a snapshot of an HTML page.
public Bitmap renderHtml(string htmlContent)
{
using (WebSession session = WebCore.CreateWebSession(WebPreferences.Default))
{
int docHeight = 0, docWidth = 0;
using (WebView view = WebCore.CreateWebView(1, 1, WebViewType.Offscreen))
{
bool finishedLoading = false;
var uri = new Uri("data:text/html," + htmlContent, UriKind.Absolute);
//uri = new Uri("http://www.google.com");
view.Source = uri;
view.LoadingFrameComplete += (s, e) =>
{
if (e.IsMainFrame)
{
finishedLoading = true;
docHeight = (int)view.ExecuteJavascriptWithResult("(function() { var bodyElmnt = document.body; var html = document.documentElement; var height = Math.max( bodyElmnt.scrollHeight, bodyElmnt.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); return height; })();");
docWidth = (int)view.ExecuteJavascriptWithResult("(function() { var bodyElmnt = document.body; var html = document.documentElement; var width = Math.max( bodyElmnt.scrollWidth, bodyElmnt.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth); return width; })();");
}
};
while (!finishedLoading)
{
Thread.Sleep(100);
WebCore.Update();
}
//view.Surface.Initialize(view, docWidth, docHeight);
view.Resize(docWidth, docHeight);
//cannot do this here because view.Surface size is (1,1)
/*
bmp = new Bitmap(docWidth, docHeight);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
BitmapSurface bmpSurface = (BitmapSurface)view.Surface;
bmpSurface.CopyTo(bmpData.Scan0, bmpSurface.RowSpan, 4, false, false);
bmp.UnlockBits(bmpData);
*/
}
using (WebView view2 = WebCore.CreateWebView(docWidth, docHeight, WebViewType.Offscreen))
{
bool finishedLoading = false;
var uri = new Uri("data:text/html," + htmlContent, UriKind.Absolute);
view2.Source = uri;
view2.LoadingFrameComplete += (s, e) =>
{
if (e.IsMainFrame)
{
finishedLoading = true;
}
};
while (!finishedLoading)
{
Thread.Sleep(100);
WebCore.Update();
}
bmp = new Bitmap(docWidth, docHeight);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
BitmapSurface bmpSurface = (BitmapSurface)view2.Surface;
bmpSurface.CopyTo(bmpData.Scan0, bmpSurface.RowSpan, 4, false, false);
bmp.UnlockBits(bmpData);
}
}
return bmp;
}
This works, but I need to create a second view using the page size that I got from the first view because when I call view.Resize() it does not resize the view's Surface so i'm getting an error trying to save the image because the sizes differ. If I call Surface.Initialize first with the new width and height then the original surface is gone and all I get is an empty white image.
How can I resize the view's surface and make this work without creating a 2nd view ?

You can't use your WebView's Surface right after you resize your WebView since it takes some time for it to resize, update and redraw. The update is done asynchronously, so you should wait for Surface.Resized event to happen. Try something like that:
using (var vw = WebCore.CreateWebView(100,100))
{
vw.Source = new Uri("website");
while (vw.IsLoading)
{
WebCore.Update();
}
var surface = (BitmapSurface)vw.Surface;
surface.SaveToPNG("screen1.png");
surface.Resized += (s, e) =>
{
// Save the updated buffer to a new PNG image.
surface.SaveToPNG("screen2.png");
WebCore.Shutdown();
};
var x = vw.ExecuteJavascriptWithResult("document.body.scrollWidth").ToString();
var y = vw.ExecuteJavascriptWithResult("document.body.scrollHeight").ToString();
vw.Resize(Convert.ToInt32(x), Convert.ToInt32(y));
WebCore.Run();
}
This snippet of code will open a website, take a screenshot, then resize your webview, wait for Resized to fire and take another screenshot.
Hope that helps.

Related

improve image quality of cropped image c#

i created a windows form c# application. It has feature to crop image. After cropping image. it show preview in other picturebox. My problem is the cropping place little bit blur in picture box. .Here is picture to understand what i meant...I want to fix it
enter image description here
here is the code i used.
{
string root = #"C:\FuelPass";
// If directory does not exist, create it.
if (!System.IO.Directory.Exists(root))
{
System.IO.Directory.CreateDirectory(root);
}
Bitmap bmp = new Bitmap(previewimg.Width, previewimg.Height);
previewimg.DrawToBitmap(bmp, new Rectangle(0, 0, previewimg.Width, previewimg.Height));
pictureBox2.DrawToBitmap(bmp, new Rectangle(pictureBox2.Location.X - previewimg.Location.X, pictureBox2.Location.Y - previewimg.Location.Y, pictureBox2.Width, pictureBox2.Height));
String savename="";
// DateTime dt = new DateTime();
// bmp.Save(#"C:\Fuelpass\" +dt.ToString()+ " .jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Save(#"C:\Fuelpass\output-" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
Form2 f2 = new Form2();
f2.Show();
// MessageBox.Show("Image has been saved");
// SaveFileDialog dialog = new SaveFileDialog();
// dialog.Filter = "JPG(*.JPG)|*.jpg";
// if (dialog.ShowDialog() == DialogResult.OK)
// {
// previewimg.Image.Save(dialog.FileName);
// pictureBox2.Image.Save(dialog.FileName);
// }
// }
}
private void PictureBoxLoad_MouseUp_1(object sender, MouseEventArgs e)
{
//pictureBox1.Image.Clone();
try
{
if (IsMouseDown == true)
{
LocationX1Y1 = e.Location;
IsMouseDown = false;
if (Rect != null)
{
Bitmap bit = new Bitmap(PictureBoxLoad.Image, PictureBoxLoad.Width, PictureBoxLoad.Height);
Bitmap cropImg = new Bitmap(Rect.Width, Rect.Height);
Graphics g = Graphics.FromImage(cropImg);
g.DrawImage(bit, 0, 0, Rect, GraphicsUnit.Pixel);
pictureBox2.Image = cropImg;
}
}
}
catch { }
}
private Rectangle GetRect()
{
Rect = new Rectangle();
Rect.X = Math.Min(LocationXY.X, LocationX1Y1.X);
Rect.Y = Math.Min(LocationXY.Y, LocationX1Y1.Y);
Rect.Width = Math.Abs(LocationXY.X - LocationX1Y1.X);
Rect.Height = Math.Abs(LocationXY.Y - LocationX1Y1.Y);
return Rect;
}

Problem with loading image from bytes array

I encountered strange behaviour when loading image from byte array aquired from stream. Most images are correct, I would say 99% of them. But i saw so far two times something like this below. Image in the middle is shown like a set of random pixels, not the real image.
Image can be loaded correctly in other client application (sliverlight) but i can't show that.
In WPF client i have something like that:
Does someone had issue like this? Or any idea what might cause it? Maybe i should look on server side (image is show in other, older client and code to load that is known to me).
Code looks like that:
public async Task<ImageCreatePictureBox> CreatePictureBox(IBaseObj pmIBaseObj, IObj pmObj)
{
var lcContainer = new Grid
{
Width = pmObj.PresObj.Width,
Height = pmObj.PresObj.Height
};
var gridBorder = new Border();
CustomImg imageControl = null;
FrameworkElement lcFrameworkElement = lcContainer;
if (!(pmIBaseObj is ImageBaseObj lcImageBaseObj))
return new ImageCreatePictureBox(null, lcContainer, lcFrameworkElement, pmObj);
if (!lcImageBaseObj.CustomBitMap)
{
try
{
var bitmapImage = BitmapImageHelper.ByteArrayToBitmapSource(lcImageBaseObj.Image, lcImageBaseObj.ImageWidth, lcImageBaseObj.ImageHeight);
imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
{
Source = bitmapImage,
Height = lcImageBaseObj.Height,
Width = lcImageBaseObj.Width
};
}
catch (Exception e)
{
var src = new BitmapImage(new Uri(Helper.GetPathToImage("dummy")));
imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
{
Source = src,
Height = lcImageBaseObj.Height,
Width = lcImageBaseObj.Width
};
Helper.WriteToDebug(e);
}
}
else
{
try
{
var bitmapImage = BitmapImageHelper.ByteArrayToBitmapSource(lcImageBaseObj.Image, lcImageBaseObj.ImageWidth, lcImageBaseObj.ImageHeight);
imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
{
Source = bitmapImage,
Height = lcImageBaseObj.Height,
Width = lcImageBaseObj.Width
};
}
catch (Exception e)
{
if (imageControl == null)
imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj);
var src = new BitmapImage(new Uri(Helper.GetPathToImage("dummy")));
imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
{
Source = src,
Height = lcImageBaseObj.Height,
Width = lcImageBaseObj.Width
};
Helper.WriteToDebug(e);
}
}
(...)
return new ImageCreatePictureBox(imageControl, lcContainer, lcFrameworkElement, pmObj);
}
public static BitmapSource ByteArrayToBitmapSource(Byte[] BArray, int imgWidth, int imgHeight)
{
try
{
var width = imgWidth;
var height = imgHeight;
var dpiX = 90d;
var dpiY = 90d;
var pixelFormat = PixelFormats.Pbgra32;
var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
var stride = bytesPerPixel * width;
var bitmap = BitmapSource.Create(width, height, dpiX, dpiY, pixelFormat, null, BArray, stride);
return bitmap;
}
catch (Exception e)
{
return BytesToBitmapImage(BArray);
}
}

Change width and heigth of saving view

I have code for saving Layout as bitmap
Here it is
public static class App
{
public static Java.IO.File _file;
public static Java.IO.File _dir;
public static Bitmap bitmap;
}
[Activity(Label = "SaveViewAsBitMap", ScreenOrientation = ScreenOrientation.Landscape, Theme = "#android:style/Theme.Black.NoTitleBar")]
public class Badge : Activity
{
public static string name_from_activity;
public static string surname_from_activity;
public string inn_from_activity;
private ImageView _imageView;
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
// Make it available in the gallery
Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
Uri contentUri = Uri.FromFile(App._file);
mediaScanIntent.SetData(contentUri);
SendBroadcast(mediaScanIntent);
// Display in ImageView. We will resize the bitmap to fit the display
// Loading the full sized image will consume to much memory
// and cause the application to crash.
int height = Resources.DisplayMetrics.HeightPixels;
int width = _imageView.Height;
App.bitmap = App._file.Path.LoadAndResizeBitmap(width, height);
if (App.bitmap != null)
{
_imageView.SetImageBitmap(App.bitmap);
App.bitmap = null;
}
// Dispose of the Java side bitmap.
GC.Collect();
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
TextView bt1 = FindViewById<TextView>(Resource.Id.Surname);
bt1.Click += Bt1_Click;
name_from_activity = Intent.GetStringExtra("Name");
surname_from_activity = Intent.GetStringExtra("Surname");
inn_from_activity = Intent.GetStringExtra("INN");
TextView Name = FindViewById<TextView>(Resource.Id.Name);
Name.Text = name_from_activity;
TextView Surname = FindViewById<TextView>(Resource.Id.Surname);
Surname.Text = surname_from_activity;
string path = "Fonts/proximanovaregular.otf";
Typeface tf = Typeface.CreateFromAsset(Assets, path); //Custom fonts for TextBoxes
Name.Typeface = tf;
Surname.Typeface = tf;
var barcodeWriter = new ZXing.Mobile.BarcodeWriter //Creating qr code using Intent data
{
Format = ZXing.BarcodeFormat.QR_CODE,
Options = new ZXing.Common.EncodingOptions //Options for QR code dimensions
{
Width = 600,
Height = 600
}
};
ImageView qr = FindViewById<ImageView>(Resource.Id.qr);
var bitmap = barcodeWriter.Write(inn_from_activity);
qr.SetImageBitmap(bitmap);
if (IsThereAnAppToTakePictures())
{
CreateDirectoryForPictures();
_imageView = FindViewById<ImageView>(Resource.Id.photo);
TakeAPicture();
}
}
//Button handler for bitmap
private void Bt1_Click(object sender, System.EventArgs e)
{
View v = FindViewById<LinearLayout>(Resource.Id.badge2);
Bitmap myBitMap = createViewBitmap(v);
Drawable drawable = new BitmapDrawable(myBitMap);
//img.SetBackgroundDrawable(drawable);
// MediaStore.Images.Media.InsertImage(ContentResolver, myBitMap, "title", "description");
saveImage(myBitMap);
Intent mediaScanIntent2 = new Intent(Intent.ActionMediaScannerScanFile);
Java.IO.File myFile = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory + "/DCIM/Camera", name_from_activity.ToString() + surname_from_activity.ToString() + ".jpg");
Android.Net.Uri contentUri = Android.Net.Uri.FromFile(myFile);
mediaScanIntent2.SetData(contentUri);
SendBroadcast(mediaScanIntent2);
}
//Creating bitmap from view via Canvas
public Bitmap createViewBitmap(View v)
{
Bitmap bitmap = Bitmap.CreateBitmap(v.Width, v.Height,
Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(bitmap);
v.Draw(canvas);
return bitmap;
}
//Check if directory exists, if no, create it
private void CreateDirectoryForPictures()
{
App._dir = new Java.IO.File(
Environment.GetExternalStoragePublicDirectory(
Environment.DirectoryPictures), "CameraAppDemo");
if (!App._dir.Exists())
{
App._dir.Mkdirs();
}
}
//Returning avialable activities
private bool IsThereAnAppToTakePictures()
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
IList<ResolveInfo> availableActivities =
PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
return availableActivities != null && availableActivities.Count > 0;
}
//Method for opening default Camera Activity and making photo
private void TakeAPicture()
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
App._file = new Java.IO.File(App._dir, String.Format("myPhoto_{0}.jpg", Guid.NewGuid()));
intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file));
StartActivityForResult(intent, 0);
}
//Method for saving image to device
public static void saveImage(Bitmap bmp)
{
try
{
using (var os = new System.IO.FileStream(Android.OS.Environment.ExternalStorageDirectory + "/DCIM/Camera/" + name_from_activity.ToString()+surname_from_activity.ToString() + ".jpg", System.IO.FileMode.CreateNew))
{
bmp.Compress(Bitmap.CompressFormat.Jpeg, 95, os);
}
}
catch (Exception e)
{
}
}
}
}
I need to save picture in 370*204 resolution
I try it like this
public Bitmap createViewBitmap(View v)
{
Bitmap bitmap = Bitmap.CreateBitmap(370, 204,
Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(bitmap);
v.Draw(canvas);
return bitmap;
}
But it not works, it saves only part of layout.
How I need to write code?
Thank's for help.
I had build a prototype for one other project that I'm using...
Try this repository
This code Bitmap.CreateBitmap(370, 204,Bitmap.Config.Argb8888); will cut the source bitmap with width 370 and height 204. The bitmap not be scaled. Because you are still use the view to draw a bitmap.
When you get the view bitmap you need to zoom the bitmap:
public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight)
{
int width = bm.Width;
int height = bm.Height;
float scaleWidth = ((float)newWidth) / width;
float scaleHeight = ((float)newHeight) / height;
Matrix matrix = new Matrix();
matrix.PostScale(scaleWidth, scaleHeight);
Bitmap newbm = Bitmap.CreateBitmap(bm, 0, 0, width, height, matrix, true);
return newbm;
}
public Bitmap createViewBitmap2(View v)
{
Bitmap bitmap = Bitmap.CreateBitmap(v.Width, v.Height,Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(bitmap);
v.Draw(canvas);
return zoomImg(bitmap, 370, 204);
}

How to save WebViewBrush as image? (UWP / Universal)

Summary: I have a collection FrameworkElements (basically web view brushes drawn on rectanlges), and I'd like to save each of these as a PNG file in my UWP app.
More details: I followed the example at https://stackoverflow.com/a/17222629/2884981 to split the content of a WebView into separate "pages".
I've put the main bits of code at the bottom.
At the bottom of GetWebPages() I have return pages;
At this point I have a list of all the "pages".
What I'd like to do, is then convert each of those pages into an image (so by the end of it I'd have a collection of PNG files, for instance).
Does anyone know how I can do this? Thanks in advance.
public async Task<WebViewBrush> GetWebViewBrush(WebView webView)
{
// resize width to content
double originalWidth = webView.Width;
var widthString = await webView.InvokeScriptAsync("eval", new[] { "document.body.scrollWidth.toString()" });
int contentWidth;
if (!int.TryParse(widthString, out contentWidth))
{
throw new Exception(string.Format("failure/width:{0}", widthString));
}
webView.Width = contentWidth;
// resize height to content
double originalHeight = webView.Height;
var heightString = await webView.InvokeScriptAsync("eval", new[] { "document.body.scrollHeight.toString()" });
int contentHeight;
if (!int.TryParse(heightString, out contentHeight))
{
throw new Exception(string.Format("failure/height:{0}", heightString));
}
webView.Height = contentHeight;
// create brush
var originalVisibilty = webView.Visibility;
webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
WebViewBrush brush = new WebViewBrush
{
SourceName = webView.Name,
Stretch = Stretch.Uniform
};
brush.Redraw();
// reset, return
webView.Width = originalWidth;
webView.Height = originalHeight;
webView.Visibility = originalVisibilty;
return brush;
}
And:
public async Task<IEnumerable<FrameworkElement>> GetWebPages(WebView webView, Windows.Foundation.Size page)
{
// ask the content its width
var widthString = await webView.InvokeScriptAsync("eval", new[] { "document.body.scrollWidth.toString()" });
int contentWidth;
if (!int.TryParse(widthString, out contentWidth))
{
throw new Exception(string.Format("failure/width:{0}", widthString));
}
webView.Width = contentWidth;
// ask the content its height
var heightString = await webView.InvokeScriptAsync("eval", new[] { "document.body.scrollHeight.toString()" });
int contentHeight;
if (!int.TryParse(heightString, out contentHeight))
{
throw new Exception(string.Format("failure/height:{0}", heightString));
}
webView.Height = contentHeight;
// how many pages will there be?
double scale = page.Width / contentWidth;
double scaledHeight = (contentHeight * scale);
double pageCount = (double) scaledHeight / page.Height;
pageCount = pageCount + ((pageCount > (int) pageCount) ? 1 : 0);
// create the pages
var pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
for (int i = 0; i < (int)pageCount; i++)
{
var translateY = -page.Height * i;
var rectanglePage = new Windows.UI.Xaml.Shapes.Rectangle
{
Height = page.Height,
Width = page.Width,
Margin = new Thickness(5),
Tag = new TranslateTransform { Y = translateY },
};
rectanglePage.Loaded += (async (s, e) =>
{
var subRectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
var subBrush = await GetWebViewBrush(webView);
subBrush.Stretch = Stretch.UniformToFill;
subBrush.AlignmentY = AlignmentY.Top;
subBrush.Transform = subRectangle.Tag as TranslateTransform;
subRectangle.Fill = subBrush;
});
pages.Add(rectanglePage);
}
return pages;
}
I'd like to save each of these as a PNG file in my UWP app.
You can get all the rectangles and show them in the ItemsControl in the NavigationCompleted event of WebView like this:
private async void webView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
MyWebViewRectangle.Fill = await GetWebViewBrush(webView);
MyPrintPages.ItemsSource = await GetWebPages(webView, new Windows.Foundation.Size(842, 595));
}
Then in a button click event you can save all the items as .png images like this:
private async void Savetoimage_Clicked(object sender, RoutedEventArgs e)
{
var piclib = Windows.Storage.KnownFolders.PicturesLibrary;
foreach (var item in MyPrintPages.Items)
{
var rect = item as Rectangle;
RenderTargetBitmap renderbmp = new RenderTargetBitmap();
await renderbmp.RenderAsync(rect);
var pixels = await renderbmp.GetPixelsAsync();
var file = await piclib.CreateFileAsync("webview.png", Windows.Storage.CreationCollisionOption.GenerateUniqueName);
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
byte[] bytes = pixels.ToArray();
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)rect.Width, (uint)rect.Height,
0, 0, bytes);
await encoder.FlushAsync();
}
}
}

GDI+ error upon upload multiple images then create thumbnails

I've got an image upload page that works just fine when I only upload the files.
I added a 'Create Thumbnail' function. It looks like the file system has a handle on the images when the thumbnail process starts.
I get the 'unspecified GDI+ error' only when the image is over about 250K. When the files are below 250K, thumbnails are created as expected.
What are my options? Is there an elegant solution here? I want something not hacky.
Also, I am using HttpFileCollection so we can upload multiple images at one time. I've tried to use .Dispose on the Thumbnail creation, but it fails before we get to this point.
public void Upload_Click(object Sender, EventArgs e)
{
string directory = Server.MapPath(#"~\images\");
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
if (hpf.ContentLength > 0)
{
string fileName = hpf.FileName;
fileName = fileName.Replace(" ", "");
hpf.SaveAs(fileName);
createThumbnail(fileName);
}
}
}
private void createThumbnail(string filename)
{
Image image = Image.FromFile(filename);
Image thumb = image.GetThumbnailImage(100,100, () => false, IntPtr.Zero);
thumb.Save(filename);
image.Dispose();
thumb.Dispose();
}
Please let me know if this works any better:
public string ImageDirectory { get { return Server.MapPath(#"~\images\"); } }
public void OnUploadClick(object sender, EventArgs e)
{
var files = HttpContext.Request.Files.AllKeys.AsEnumerable()
.Select(k =>HttpContext.Request.Files[k]);
foreach(var file in files)
{
if(file.ContentLength <= 0)
continue;
string savePath = GetFullSavePath(file);
var dimensions = new Size(100, 100);
CreateThumbnail(file,savePath,dimensions);
}
}
private void CreateThumbnail(HttpPostedFile file,string savePath, Size dimensions)
{
using (var image = Image.FromStream(file.InputStream))
{
using (var thumb = image.GetThumbnailImage(dimensions.Width, dimensions.Height, () => false, IntPtr.Zero))
{
thumb.Save(savePath);
}
}
}
private string GetFullSavePath(HttpPostedFile file)
{
string fileName = System.IO.Path.GetFileName(file.FileName).Replace(" ", "");
string savePath = System.IO.Path.Combine(this.ImageDirectory, fileName);
return savePath;
}
Edit -
The foreach should have followed more to this pattern:
var files = HttpContext.Request.Files.AllKeys.AsEnumerable()
.Select(k =>HttpContext.Request.Files[k]);
foreach(var file in files)
{
}
You can try this code to create your thumbnails.
MemoryStream ms = new MemoryStream(File.ReadAllBytes(path));
Bitmap originalBMP = new Bitmap(ms);
int maxWidth = 200;
int maxHeight = 200;
// Calculate the new image dimensions
int origWidth = originalBMP.Width;
int origHeight = originalBMP.Height;
double sngRatio = Convert.ToDouble(origWidth) / Convert.ToDouble(origHeight);
// New dimensions
int newWidth = 0;
int newHeight = 0;
try
{
// max 200 by 200
if ((origWidth <= maxWidth && origHeight <= maxHeight) || origWidth <= maxWidth)
{
newWidth = origWidth;
newHeight = origHeight;
}
else
{
// Width longer (shrink width)
newWidth = 200;
newHeight = Convert.ToInt32(Convert.ToDouble(newWidth) / sngRatio);
}
// Create a new bitmap which will hold the previous resized bitmap
Bitmap newBMP = new Bitmap(originalBMP, newWidth, newHeight);
// Create a graphic based on the new bitmap
Graphics oGraphics = Graphics.FromImage(newBMP);
// Set the properties for the new graphic file
oGraphics.SmoothingMode = SmoothingMode.AntiAlias;
oGraphics.InterpolationMode = InterpolationMode.High;
// Draw the new graphic based on the resized bitmap
oGraphics.CompositingQuality = CompositingQuality.HighSpeed;
oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
// Save the new graphic file to the server
EncoderParameters p = new EncoderParameters(1);
p.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 70); // Percent Compression
MemoryStream savedBmp = new MemoryStream();
newBMP.Save(savedBmp, ImageCodecInfo.GetImageEncoders()[1], p);
// Once finished with the bitmap objects, we deallocate them.
originalBMP.Dispose();
newBMP.Dispose();
oGraphics.Dispose();
savedBmp.Dispose();
Certainly a bit more work but it does give you greater control.

Categories