How resize HttpPostedFileWrapper? - c#

I need resize this image proportionally heigth 411px.
how do this?
[HttpPost]
public WrappedJsonResult UploadImage(HttpPostedFileWrapper imageFile, int id)
{
if (imageFile == null || imageFile.ContentLength == 0)
{
return new WrappedJsonResult
{
Data = new
{
IsValid = false,
Message = "No file was uploaded.",
ImagePath = string.Empty
}
};
}
var fileName = String.Format("{0}_{1}.jpg", id, Guid.NewGuid().ToString());
var imagePath = Path.Combine(Server.MapPath(Url.Content("~/Content/UploadPhoto")), fileName);
imageFile.SaveAs(imagePath);
}

public ActionResult UploadImage(HttpPostedFileBase imageFile, int id)
{
if (imageFile == null || imageFile.ContentLength == 0)
{
return new WrappedJsonResult
{
Data = new
{
IsValid = false,
Message = "No file was uploaded.",
ImagePath = string.Empty
}
};
}
var fileName = String.Format("{0}_{1}.jpg", id, Guid.NewGuid().ToString());
var imagePath = Path.Combine(Server.MapPath(Url.Content("~/Content/UploadPhoto")), fileName);
using (var input = new Bitmap(imageFile.InputStream))
{
int width;
int height;
if (input.Width > input.Height)
{
width = 411;
height = 411 * input.Height / input.Width;
}
else
{
height = 411;
width = 411 * input.Width / input.Height;
}
using (var thumb = new Bitmap(width, height))
using (var graphic = Graphics.FromImage(thumb))
{
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.AntiAlias;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.DrawImage(input, 0, 0, width, height);
using (var output = System.IO.File.Create(imagePath))
{
thumb.Save(output, ImageFormat.Jpeg);
}
}
}
...
}
By the way you will notice that I have replaced HttpPostedFileWrapper with HttpPostedFileBase in the action signature as this is the correct type to use.

Related

How to compress/resize and display video in the view

I am displaying images and video as the thumbnail in the view page. Whenever a user uploads image or video I am saving URL into DB and files into the folder. While displaying I am resizing image size on the server side to reduce the page load time. I am able to compress the images and but not the videos. How to resize or compress the video same as the image. At present videos are not displaying because using the same logic to retrieve both image and videos.
View :
Database:
ImageHandler.ashx.cs :
namespace ResoucesProject
{
public class ImageHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
var fileName = ConfigurationManager.AppSettings["BasePath"] + context.Request.QueryString["file"];
var filePath = context.Server.MapPath(fileName);
var fileWidth = 300;
if (!string.IsNullOrEmpty(context.Request.QueryString["width"]))
{
int tempWidth;
if (int.TryParse(context.Request.QueryString["width"], out tempWidth) && tempWidth < 3000) // set a max limit so people don't request huge files
fileWidth = tempWidth;
}
var fileHeight = 300;
if (!string.IsNullOrEmpty(context.Request.QueryString["height"]))
{
int tempHeight;
if (int.TryParse(context.Request.QueryString["height"], out tempHeight) && tempHeight < 3000) // set a max limit so people don't request huge files
fileHeight = tempHeight;
}
context.Response.AddHeader("content-disposition",
string.Format("attachment; filename={0}", fileName));
if (File.Exists(filePath))
{
var buffer = GetResizedImage(filePath, fileWidth, fileHeight);
if (buffer == null)
{
return;
}
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.End();
byte[] bytes = File.ReadAllBytes(filePath);
context.Response.BinaryWrite(bytes);
}
else
{
throw new HttpException(404, "Invalid photo name.");
}
}
private static byte[] GetResizedImage(string path, int width, int height)
{
try
{
var imgIn = new Bitmap(path);
double y = imgIn.Height;
double x = imgIn.Width;
double factor = 1;
if (width > 0)
{
factor = width / x;
}
else if (height > 0)
{
factor = height / y;
}
var outStream = new MemoryStream();
var imgOut = new Bitmap((int)(x * factor), (int)(y * factor));
// Set DPI of image (xDpi, yDpi)
imgOut.SetResolution(72, 72);
var g = Graphics.FromImage(imgOut);
g.Clear(Color.White);
g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)),
new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel);
imgOut.Save(outStream, GetImageFormat(path));
return outStream.ToArray();
}
catch (ArgumentException e)
{
Console.WriteLine(e.Message);
return null;
}
}
private static ImageFormat GetImageFormat(string path)
{
switch (Path.GetExtension(path))
{
case ".bmp": return ImageFormat.Bmp;
case ".gif": return ImageFormat.Gif;
case ".jpg": return ImageFormat.Jpeg;
case ".png": return ImageFormat.Png;
}
return ImageFormat.Jpeg;
}
}
}
View :
#foreach (var item in Model)
{
<tr>
<td>
<img src="~/ImageHandler.ashx?file=#Html.DisplayFor(modelItem =>item.image_url)&width=100&height=100" style="width:100px; height:100px;" />
</td>
</tr>
}
#foreach (var item in Model)
{
<tr>
<td>
<img src="~/ImageHandler.ashx?file=#Html.DisplayFor(modelItem =>item.image_url)&width=100&height=100" style="width:100px; height:100px;" />
</td>
</tr>
}

SharpDX 3 loading .DDS to apply onto a 3d model (C#)

I'm attempting to create a model viewer for a game to try and learn SharpDX but the game uses .DDS files and the viewer can only read .BMPs. I've looked far and wide on the webs and the only things I can find are load them but don't seem to work for SharpDX (I don't know im a noob :D)
using SharpDX.Direct3D11;
using SharpDX.WIC;
namespace ModelViewer.Programming.GraphicClasses
{
public class TextureClass
{
public ShaderResourceView TextureResource { get; private set; }
public bool Init(Device device, string fileName)
{
try
{
using (var texture = LoadFromFile(device, new ImagingFactory(), fileName))
{
ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
{
Format = texture.Description.Format,
Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D,
};
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = -1;
TextureResource = new ShaderResourceView(device, texture, srvDesc);
device.ImmediateContext.GenerateMips(TextureResource);
}
return true;
}
catch
{
return false;
}
}
public void Shutdown()
{
TextureResource?.Dispose();
TextureResource = null;
}
public Texture2D LoadFromFile(Device device, ImagingFactory factory, string fileName)
{
using (var bs = LoadBitmap(factory, fileName))
return CreateTextureFromBitmap(device, bs);
}
public BitmapSource LoadBitmap(ImagingFactory factory, string filename)
{
var bitmapDecoder = new BitmapDecoder(factory, filename, DecodeOptions.CacheOnDemand);
var result = new FormatConverter(factory);
result.Initialize(bitmapDecoder.GetFrame(0), SharpDX.WIC.PixelFormat.Format32bppPRGBA, BitmapDitherType.None, null, 0.0, BitmapPaletteType.Custom);
return result;
}
public Texture2D CreateTextureFromBitmap(Device device, BitmapSource bitmapSource)
{
int stride = bitmapSource.Size.Width * 4;
using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
{
bitmapSource.CopyPixels(stride, buffer);
return new Texture2D(device, new Texture2DDescription()
{
Width = bitmapSource.Size.Width,
Height = bitmapSource.Size.Height,
ArraySize = 1,
BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget,
Usage = ResourceUsage.Default,
CpuAccessFlags = CpuAccessFlags.None,
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
MipLevels = 1,
OptionFlags = ResourceOptionFlags.GenerateMipMaps,
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
},
new SharpDX.DataRectangle(buffer.DataPointer, stride));
}
}
}
}
I have a feeling this will need to be completely redone to utilize the DDS format. Is it easier to simply read one and then convert it to a bitmap?

How can I return the image?

It is created by a coordinate system with the two codesnippets listed below. Unfortunately, the second code snippet saves the image to the desktop. I would like to have the "image" returned. How can I return the image of the coordinate system? ( I have a method which has a return value as a picture )
At the end it should be preview = image;
So that from the coordinate system an "image" and not to the desktop is stored, but I can return it.
var stream = new MemoryStream();
var pngExporter = new PngExporter { Width = 600, Height = 400, Background = OxyColors.White };
pngExporter.Export(plotModel, stream);
preview = stream; //Does not work unfortunately
var pngExporter = new PngExporter { Width = 350, Height = 350, Background = OxyColors.White };
pngExporter.ExportToFile(plotModel, #"C:\Users\user\Desktop\test.png");
public bool createPreview(out string errorMessage, out System.Drawing.Image preview, int pWidth, int pHeight, int pMargin)
{
errorMessage = null;
preview = null;
bool folded = false;
try
{
PlotModel plotModel = new PlotModel { Title = "Vorschaukomponente" };
plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Bottom, MinimumPadding = 0.1, MaximumPadding = 0.1 });
plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Left, MinimumPadding = 0.1, MaximumPadding = 0.1 });
var series1 = new OxyPlot.Series.LineSeries
{
LineStyle = LineStyle.None,
MarkerType = MarkerType.Circle,
MarkerSize = 2,
MarkerFill = OxyColors.Transparent,
MarkerStroke = OxyColors.Black,
MarkerStrokeThickness = 1
};
if (pointX.Count == pointY.Count)
{
for (int i = 0; i < pointX.Count; i++)
{
for (int g = i; g < pointY.Count; g++)
{
series1.Points.Add(new DataPoint(pointX[i], pointY[g]));
Console.WriteLine(i+1 + " | "+ pointX[i].ToString() + "/" + pointY[g]);
break;
}
}
series1.Smooth = true;
plotModel.Series.Add(series1);
try
{
var stream = new MemoryStream();
var pngExporter = new PngExporter { Width = 600, Height = 400, Background = OxyColors.White };
pngExporter.Export(plotModel, stream);
preview = stream;
// var pngExporter = new PngExporter { Width = 350, Height = 350, Background = OxyColors.White };
// pngExporter.ExportToFile(plotModel, #"C:\Users\user\Desktop\test.png");
folded = true;
}
catch (Exception exc)
{
System.Diagnostics.Debug.WriteLine(exc.Message);
errorMessage = "Es konnt kein Bild erstellt werden.";
folded = false;
}
}
else
{
errorMessage = "Es ist nicht die gleiche Anzahl von xen und yen vorhanden.";
folded = false;
}
}
catch (Exception)
{
errorMessage= "Es trat ein unerwarteter Fehler auf";
folded = false;
}
return folded;
}
First of all, i suggest you to use System.Windows.Media.Imaging.BitmapImage rather than System.Drawing.Image since you are in the WPF-World.
After you changed that, you can easily write
preview.BeginInit();
preview.StreamSource = stream;
preview.EndInit();
after the PngExporter did its job.
Unfortunately i cannot test it since i dont have your pointX and pointY - Collections.
Let me know if that helps
Looks like you want Image.FromStream(stream)

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.

Grid.Add.Children(UIElement) returns Parameter is incorrect exception

I am trying to add border in two pivot items.
When my border is added to grid in pivot item for the first time everything is working fine. But when i try to add border second time in same pivot item it throws an exception "The parameter is incorrect"
here is my code :
private void pivot_item1Loaded()
{
WebClient webClient2011 = new WebClient();
string Url2011 = "http://hostname/Details/Images?year=2011" + "&time=" + System.DateTime.UtcNow;
webClient2011.OpenReadAsync(new Uri(Url2011));
webClient2011.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted2011);
}
private void pivot_item2Loaded()
{
WebClient webClient2012 = new WebClient();
string Url2012 = "http://hostname/Details/Images?year=2012" +"&time="+ System.DateTime.UtcNow;
webClient2012.OpenReadAsync(new Uri(Url2012));
webClient2012.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted2012);
}
public void webClient_OpenReadCompleted2011(object sender, OpenReadCompletedEventArgs e)
{
StringBuilder output = new StringBuilder();
try
{
using (XmlReader reader = XmlReader.Create(e.Result))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == "iconPath")
{
string iconPath = reader.ReadElementContentAsString();
iconImages2011.Add(iconPath);
}
if (reader.Name == "imagePath")
{
string imagePath = reader.ReadElementContentAsString();
fullScreenImages2011.Add(imagePath);
}
}
}
}
int numOfRows = (iconImages2011.Count) / 3 + 1;
for (int j = 0; j < numOfRows; j++)
{
//pivot_item1
ContentPanel2011.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(150) });
}
int rowCount = 0;
int columnCount = 0;
for (int i = 0; i < iconImages2011.Count; i++)
{
Border border2011 = new Border();
border2011.Background = new SolidColorBrush(Colors.Blue);
border2011.Height = 110;
border2011.Width = 110;
border2011.CornerRadius = new CornerRadius(10);
Canvas canvas2011 = new Canvas();
canvas2011.Height = 110;
canvas2011.Width = 110;
BitmapImage AppImage = new BitmapImage(new Uri(iconImages2011[i], UriKind.Absolute));
Image img = new Image();
img.Source = AppImage;
img.Width = 90;
img.Height = 90;
img.Stretch = Stretch.Fill;
img.Margin = new Thickness(10, 10, 10, 10);
canvas2011.Children.Add(img);
border2011.Child = canvas2011;
border2011.Name = i.ToString();
Grid.SetColumn(border2011, columnCount);
Grid.SetRow(border2011, rowCount);
ContentPanel2011.Children.Add(border2011);
pivot2011.Content = ContentPanel2011;
if (columnCount < 2)
{
columnCount++;
}
else if (columnCount == 2)
{
columnCount = 0;
rowCount++;
}
}
}
catch (Exception x)
{
MessageBox.Show(x.Message);
}
}
This code works for the first time but gives exception after that and ContentPanel2011 viz pivot_item1 do not get filled with border2011
It is done.
just set content property on pivots to null before before setting the content again.
I have just added:
pivot2011.Content = null;
pivot2012.Content = null;
in pivot_item1Loaded() and pivot_item2Loaded()
and it is working fine.

Categories