C# ImageButton Picture Resolution - asp.net

I'm trying to make a simple picture thumbnail application. I've searched the web and have found fairly complicated thumbnail apps, to simple ones. I have a good one working, If I could get the ImageButton Resolution looking good. Currently, everything works fine, but the resoultion of the buttons is horrible (i've tried various width/height variations).
I simply iterate through an array of button Image's and set their properties. I call ThumbnailSize() to set the width/height of the Imagebutton.
The code is kind of sloppy as of right now, but thats besides the point. I want to know if there is a way to keep or increase the ImageButton resolution while taking a picture (800x600+/-) and shrinking it into a Imagebutton.
string[] files = null;
files = Directory.GetFiles(Server.MapPath("Pictures"), "*.jpg");
ImageButton[] arrIbs = new ImageButton[files.Length];
for (int i = 0; i < files.Length; i++)
{
arrIbs[i] = new ImageButton();
arrIbs[i].ID = "imgbtn" + Convert.ToString(i);
arrIbs[i].ImageUrl = "~/Gallery/Pictures/pic" + i.ToString() + ".jpg";
ThumbNailSize(ref arrIbs[i]);
//arrIbs[i].BorderStyle = BorderStyle.Inset;
arrIbs[i].AlternateText = System.IO.Path.GetFileName(Convert.ToString(files[i]));
arrIbs[i].PostBackUrl = "default.aspx?img=" + "pic" + i.ToString();
pnlThumbs.Controls.Add(arrIbs[i]);
}
}
public ImageButton ThumbNailSize(ref ImageButton imgBtn)
{
//Create Image with ImageButton path, and determine image size
System.Drawing.Image img =
System.Drawing.Image.FromFile(Server.MapPath(imgBtn.ImageUrl));
if (img.Height > img.Width)
{
//Direction is Verticle
imgBtn.Height = 140;
imgBtn.Width = 90;
return imgBtn;
}
else
{
//Direction is Horizontal
imgBtn.Height = 110;
imgBtn.Width = 130;
return imgBtn;
}
}

This function will proportionally resize a Size structure. Just provide it the maximum height/width and it will return a size that fits within that rectangle.
/// <summary>
/// Proportionally resizes a Size structure.
/// </summary>
/// <param name="sz"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
/// <returns></returns>
public static Size Resize(Size sz, int maxWidth, int maxHeight)
{
int height = sz.Height;
int width = sz.Width;
double actualRatio = (double)width / (double)height;
double maxRatio = (double)maxWidth / (double)maxHeight;
double resizeRatio;
if (actualRatio > maxRatio)
// width is the determinate side.
resizeRatio = (double)maxWidth / (double)width;
else
// height is the determinate side.
resizeRatio = (double)maxHeight / (double)height;
width = (int)(width * resizeRatio);
height = (int)(height * resizeRatio);
return new Size(width, height);
}

You need to scale the image according to its original size. Just setting the size will definately cause scaling issues.
Have a look at this link
C#: Resize An Image While Maintaining Aspect Ratio and Maximum Height

Related

How do I render a higher quality image via CustomRenderer in iOS with Xamarin Forms?

This is fairly straight forward, but I have some custom ShellRenderers for my App in Xamarin Forms, and I'm having issues with the scaling of images. In particular, Android looks fantastic with the more pixel-dense image (800x200). It looks great on every screen.
The renderer just ensures that the top of the screen is made of the "theme" color, and is presented in the center of the it. It's that simple/straight-forward.
On iOS, it looks awful and blurred. I'm not sure if there's something I need to set or update (or maybe a different graphics stack?) to make it render with higher pixel density... See my attached renderer:
public class CustomShellRenderer : ShellRenderer
{
#region Methods
protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
{
var renderer = base.CreateShellSectionRenderer(shellSection);
if (renderer != null)
{
var navigationBar = (renderer as ShellSectionRenderer).NavigationBar;
if (navigationBar != null)
{
navigationBar.BarTintColor = Colors.LightColor.ToUIColor(); //static colors
navigationBar.TintColor = Colors.LightColor.ToUIColor();
using (var logo = UIImage.FromResource(typeof(Images).Assembly, "Path.To.Logo.png"))
{
var statusFrame = UIApplication.SharedApplication.StatusBarFrame;
var navigationFrame = navigationBar.Frame;
var width = Math.Max(navigationFrame.Width, statusFrame.Width);
var fullArea = new CGRect(0, 0, width, navigationFrame.Height + statusFrame.Height);
UIGraphics.BeginImageContext(fullArea.Size);
var backgroundColor = Colors.PrimaryColor.ToUIColor();
backgroundColor.SetFill();
UIGraphics.RectFill(fullArea);
var logoArea = new CGRect(width * .35, statusFrame.Height, width * .3, navigationFrame.Height);
logo.Draw(logoArea);
var backgroundImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
(renderer as ShellSectionRenderer).NavigationBar.SetBackgroundImage(backgroundImage, UIBarMetrics.Default);
backgroundImage.Dispose();
}
}
}
return renderer;
}
#endregion
}
Any thoughts? Right now, the problem is that when it renders, there is an 800x200 image trying to squeeze into... 140x30 or so space on some emulators...
Thank you!

Xamarin.Forms - Strange height issue with my responsive WebViews on iOS

I have a ListView and inside that I want to bind multiple webviews which all vary in height. I want to calculate the height of each webview based on it's content and display it accordingly.
It works on Android - on iOS all WebViews are FAR too big
await System.Threading.Tasks.Task.Delay(100);
var result = (double)webView.ScrollView.ContentSize.Height;
_webView.HeightRequest = result;
The strange thing is: the MORE html characters the webview has, the bigger it gets. So I could add just one character and another 50px will be added to the height.
It is a lot of code to post here but here is a link to the project on github:
https://github.com/SlimboTimbo/MultipleWebViews
After checking the project , have found the reason why not works in iOS Device .
The reason is that the width of webView.ScrollView.ContentSize is not correct , is too small that is 27 . Therefore , it can not show correctly .
System.Console.WriteLine("----" + resultWidth + "-----"+ resultHeight + "----"+ _webView.Width);
Output :
2020-06-04 11:19:58.066542+0800 MultipleWebViews.iOS[50674:1690400] ----27-----642----375
Solution :
You can caluculate the height by the width of HybridWebView, and set the calcualted height for HybridWebView .
DidFinishNavigation method code as follow :
public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
try
{
var _webView = webViewRenderer.Element as HybridWebView;
if (_webView != null)
{
await System.Threading.Tasks.Task.Delay(100);
var resultWidth = (double)webView.ScrollView.ContentSize.Width;
var resultHeight = (double)webView.ScrollView.ContentSize.Height;
System.Console.WriteLine("----" + resultWidth + "-----"+ resultHeight + "----"+ _webView.Width);
double result = MeasureTextHeightSize(_webView.messageContent, _webView.Width, UIFont.LabelFontSize, null);
_webView.HeightRequest = result;
MessagingCenter.Send<Object, PassModel>(this, "LoadFinished", new PassModel(_webView.Id, Convert.ToDouble(result)));
}
}
catch (Exception ex)
{
Console.WriteLine("Error at HybridWebViewRenderer LoadingFinished: " + ex.Message);
}
}
MeasureTextHeightSize ( Calculate the height method )
private double MeasureTextHeightSize(string text, double width, double fontSize, string fontName = null)
{
var nsText = new NSString(text);
var boundSize = new SizeF((float)width, float.MaxValue);
var options = NSStringDrawingOptions.UsesFontLeading | NSStringDrawingOptions.UsesLineFragmentOrigin;
if (fontName == null)
{
fontName = "HelveticaNeue";
}
var attributes = new UIStringAttributes
{
Font = UIFont.FromName(fontName, (float)fontSize)
};
var sizeF = nsText.GetBoundingRect(boundSize, options, attributes, null).Size;
//return new Xamarin.Forms.Size((double)sizeF.Width, (double)sizeF.Height);
return (double)sizeF.Height;
}
The Effect :
Note : You can modify the fontSize of this method according to your current system font size . And also can custom the return value ,such as return (double)sizeF.Height + 10 to fit screen .

How to generate image Thumb minimal coding

How to generate image as Thumb in simple way i think minimal coding on asp.net,
Then after how to save particular folder
I would not recommend to use the "Image.GetThumbnailImage" method because of the poor quality
(search "Image.GetThumbnailImage quality" on your favorite search engine...)
Here is a code snippet:
void GenerateThumbnail(string sourceImagePath, string destImagePath, int width, int height, System.Drawing.Imaging.ImageFormat destImageFormat)
{
using (var destImage = new System.Drawing.Bitmap(width, height))
{
using (var g = System.Drawing.Graphics.FromImage(destImage))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
using (var sourceImage = System.Drawing.Image.FromFile(sourceImagePath))
{
g.DrawImage(sourceImage, new System.Drawing.Rectangle(0, 0, width, height));
}
destImage.Save(destImagePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
OR - you can use Piczard (Piczard)
Here are some usage examples:
// 50% thumbnail (Jpeg image format)
var filter = new CodeCarvings.Piczard.ImageTransformation(50);
filter.SaveProcessedImageToFileSystem("~/MySourceImage.jpg", "~/MyDestImage.jpg");
// Fixed size thumbnail 400x200 (PNG image format)
var filter2 = new CodeCarvings.Piczard.FixedResizeConstraint(400, 200);
filter.SaveProcessedImageToFileSystem("~/MySourceImage2.jpg", "~/MyDestImage2.png");
I have tried like this so cool..!!,
public void ThumbGenerate(string sourcepath,string thumbsavepath, int width, int height)
{
Image image = Image.FromFile(sourcepath);
Image thumb = image.GetThumbnailImage(width, height, () => false, IntPtr.Zero);
thumb.Save(Path.ChangeExtension(thumbsavepath, "jpg"));
}
Note :You can change extension what you like something jpg,jpeg,png

please help me with image.GetThumbnailImage (it create very low quality image)

i use this code to create thumbnails
System.Drawing.Image.GetThumbnailImageAbort abort = new System.Drawing.Image.GetThumbnailImageAbort(this.ThumbnailCallback);
System.Drawing.Image image2 = image.GetThumbnailImage((int)Math.Round((double)wid / difference), (int)Math.Round((double)hei / difference), abort, IntPtr.Zero);
image2.Save(str2, System.Drawing.Imaging.ImageFormat.Jpeg);
image2.Dispose();
but i get this very low quality image
but it is suposed to be like this one
what i am making wrong
or how can achieve this
Your problem is not really with the GetThumbnailImage() method, but instead in how you are saving the file. You need to specify the quality level of the JPEG you are saving, or it seems it always defaults to a very low value.
Consider this code as a guide (it's from an old .NET 2.0 project; the code still works fine compiled against 4.0, but there may be a more direct method in 4.0; I've never had reason to check)
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegEncoder = null;
for (int x = 0; x < encoders.Length; x++) {
if (string.Compare(encoders[x].MimeType, "image/jpeg", true) == 0) {
jpegEncoder = encoders[x];
break;
}
}
if (jpegEncoder == null) throw new ApplicationException("Could not find JPEG encoder!");
EncoderParameters prms = new EncoderParameters(1);
prms.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L);
bitmap.Save(fileName, jpegEncoder, prms);
Here is another solution that should always work without fetching out the encoder. It resizes keeping relation between width & heigh ... modify for your needs.
/// <summary>
/// Resize an image with high quality
/// </summary>
public static Image ResizeImage(Image srcImage, int width)
{
var b = new Bitmap(width, srcImage.Height * width / srcImage.Width);
using (var g = Graphics.FromImage((Image)b))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(srcImage, 0, 0, b.Width, b.Height);
}
return b;
}

What is the "best" way to create a thumbnail using ASP.NET? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Story: The user uploads an image that will be added to a photo gallery. As part of the upload process, we need to A) store the image on the web server's hard drive and B) store a thumbnail of the image on the web server's hard drive.
"Best" here is defined as
Relatively easy to implement, understand, and maintain
Results in a thumbnail of reasonable quality
Performance and high-quality thumbnails are secondary.
GetThumbnailImage would work, but if you want a little better quality you can specify your image options for the BitMap class and save your loaded image into there. Here is some sample code:
Image photo; // your uploaded image
Bitmap bmp = new Bitmap(resizeToWidth, resizeToHeight);
graphic = Graphics.FromImage(bmp);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight);
imageToSave = bmp;
This provides better quality than GetImageThumbnail would out of the box
I suppose your best solution would be using the GetThumbnailImage from the .NET Image class.
// Example in C#, should be quite alike in ASP.NET
// Assuming filename as the uploaded file
using ( Image bigImage = new Bitmap( filename ) )
{
// Algorithm simplified for purpose of example.
int height = bigImage.Height / 10;
int width = bigImage.Width / 10;
// Now create a thumbnail
using ( Image smallImage = image.GetThumbnailImage( width,
height,
new Image.GetThumbnailImageAbort(Abort), IntPtr.Zero) )
{
smallImage.Save("thumbnail.jpg", ImageFormat.Jpeg);
}
}
Using an example above and some from a couple of other places, here is an easy function to just drop in (thanks to Nathanael Jones and others here).
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
public static void ResizeImage(string FileNameInput, string FileNameOutput, double ResizeHeight, double ResizeWidth, ImageFormat OutputFormat)
{
using (System.Drawing.Image photo = new Bitmap(FileNameInput))
{
double aspectRatio = (double)photo.Width / photo.Height;
double boxRatio = ResizeWidth / ResizeHeight;
double scaleFactor = 0;
if (photo.Width < ResizeWidth && photo.Height < ResizeHeight)
{
// keep the image the same size since it is already smaller than our max width/height
scaleFactor = 1.0;
}
else
{
if (boxRatio > aspectRatio)
scaleFactor = ResizeHeight / photo.Height;
else
scaleFactor = ResizeWidth / photo.Width;
}
int newWidth = (int)(photo.Width * scaleFactor);
int newHeight = (int)(photo.Height * scaleFactor);
using (Bitmap bmp = new Bitmap(newWidth, newHeight))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage(photo, 0, 0, newWidth, newHeight);
if (ImageFormat.Png.Equals(OutputFormat))
{
bmp.Save(FileNameOutput, OutputFormat);
}
else if (ImageFormat.Jpeg.Equals(OutputFormat))
{
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
using (encoderParameters = new System.Drawing.Imaging.EncoderParameters(1))
{
// use jpeg info[1] and set quality to 90
encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);
bmp.Save(FileNameOutput, info[1], encoderParameters);
}
}
}
}
}
}
Here is an extension method in VB.NET for the Image Class
Imports System.Runtime.CompilerServices
Namespace Extensions
''' <summary>
''' Extensions for the Image class.
''' </summary>
''' <remarks>Several usefull extensions for the image class.</remarks>
Public Module ImageExtensions
''' <summary>
''' Extends the image class so that it is easier to get a thumbnail from an image
''' </summary>
''' <param name="Input">Th image that is inputted, not really a parameter</param>
''' <param name="MaximumSize">The maximumsize the thumbnail must be if keepaspectratio is set to true then the highest number of width or height is used and the other is calculated accordingly. </param>
''' <param name="KeepAspectRatio">If set false width and height will be the same else the highest number of width or height is used and the other is calculated accordingly.</param>
''' <returns>A thumbnail as image.</returns>
''' <remarks>
''' <example>Can be used as such.
''' <code>
''' Dim _NewImage as Image
''' Dim _Graphics As Graphics
''' _Image = New Bitmap(100, 100)
''' _Graphics = Graphics.FromImage(_Image)
''' _Graphics.FillRectangle(Brushes.Blue, New Rectangle(0, 0, 100, 100))
''' _Graphics.DrawLine(Pens.Black, 10, 0, 10, 100)
''' Assert.IsNotNull(_Image)
''' _NewImage = _Image.ToThumbnail(10)
''' </code>
''' </example>
''' </remarks>
<Extension()> _
Public Function ToThumbnail(ByVal Input As Image, ByVal MaximumSize As Integer, Optional ByVal KeepAspectRatio As Boolean = True) As Image
Dim ReturnImage As Image
Dim _Callback As Image.GetThumbnailImageAbort = Nothing
Dim _OriginalHeight As Double
Dim _OriginalWidth As Double
Dim _NewHeight As Double
Dim _NewWidth As Double
Dim _NormalImage As Image
Dim _Graphics As Graphics
_NormalImage = New Bitmap(Input.Width, Input.Height)
_Graphics = Graphics.FromImage(_NormalImage)
_Graphics.DrawImage(Input, 0, 0, Input.Width, Input.Height)
_OriginalHeight = _NormalImage.Height
_OriginalWidth = _NormalImage.Width
If KeepAspectRatio = True Then
If _OriginalHeight > _OriginalWidth Then
If _OriginalHeight > MaximumSize Then
_NewHeight = MaximumSize
_NewWidth = _OriginalWidth / _OriginalHeight * MaximumSize
Else
_NewHeight = _OriginalHeight
_NewWidth = _OriginalWidth
End If
Else
If _OriginalWidth > MaximumSize Then
_NewWidth = MaximumSize
_NewHeight = _OriginalHeight / _OriginalWidth * MaximumSize
Else
_NewHeight = _OriginalHeight
_NewWidth = _OriginalWidth
End If
End If
Else
_NewHeight = MaximumSize
_NewWidth = MaximumSize
End If
ReturnImage = _
_NormalImage.GetThumbnailImage(Convert.ToInt32(_NewWidth), Convert.ToInt32(_NewHeight), _Callback, _
IntPtr.Zero)
_NormalImage.Dispose()
_NormalImage = Nothing
_Graphics.Dispose()
_Graphics = Nothing
_Callback = Nothing
Return ReturnImage
End Function
End Module
End Namespace
Sorry the code tag doesn't like vb.net code.
You can use the Image.GetThumbnailImage function to do it for you.
http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx (.NET 3.5)
http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage(VS.80).aspx (.NET 2.0)
public bool ThumbnailCallback()
{
return false;
}
public void Example_GetThumb(PaintEventArgs e)
{
Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
Bitmap myBitmap = new Bitmap("Climber.jpg");
Image myThumbnail = myBitmap.GetThumbnailImage(40, 40, myCallback, IntPtr.Zero);
e.Graphics.DrawImage(myThumbnail, 150, 75);
}
Avoid GetThumbnailImage - it will provide very unpredictable results, since it tries to use the embedded JPEG thumbnail if available - even if the embedded thumbnail is entirely the wrong size. DrawImage() is a much better solution.
Wrap your bitmap in a using{} clause - you don't want leaked handles floating around...
Also, you'll want to set your Jpeg encoding quality to 90, which is where GDI+ seems to shine the best:
System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.EncoderParameters encoderParameters;
encoderParameters = new System.Drawing.Imaging.EncoderParameters(1);
encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);
thumb.Save(ms, info[1], encoderParameters);

Resources