Limit image proportions as inline attachment in c# constructed email
-
21-12-2019 - |
Frage
Good day,
How can I reduce / limit the size of an image as an inline attachment in a c# email? The image that appears on the email is physically HUGE, and I want to scale it down to around 475px x 475px.
HTML:
...
<td style="max-width: 475px; max-height: 475px">
<img style="width:475px; height: 475px;" id="Img1" src="cid:Product" />
</td>
<td style="width: 475px">
<div class="jamHeader">
<img id="jamHeaderImage" src="cid:Header" />
</div>
<div class="labelContainer">
<h1 class="title-block">
<p id="SoftwareName">"xxxxxxxxxx"</p>
</h1>
<div class="productInfo">
<div id="EmailDescription">
xxxxxxxxxx
This link expires in 24 hours if not redeemed."
</div>
</div>
</div>
</td>
...
Code to attach image
if (!string.IsNullOrEmpty(productImage))
{
System.Net.Mail.Attachment product = new System.Net.Mail.Attachment(productImage);
product.ContentId = "Product";
product.ContentDisposition.Inline = true;
product.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
message.Attachments.Add(product);
}
As seen on this site, the max-width
and max-height
css styles are no longer supported in Outlook 2007 up. The images are read from the disk, added as an attachment and given a content ID which matches the content ID placeholder image tag on the html page. The image doesn't resize to smaller proportions, and... its scaring the other elements on the page by making them feel really...really tiny.
How can I overcome this?
Lösung
I have dealt with this problem. Real problem is you are using not Embedded IE in Outlook, but Word rendering engine. It has more quirks then IE6 and IE7 combined. I solved the problem by scaling the image in server and using it.
Andere Tipps
Huge workaround, but this is both a response and answer to what @Margus was getting to.
Scale the image on the server: Code I used-
private void ResizeImage(string path)
{
var image = System.Drawing.Image.FromFile(path);
var widthAndHeightMax = 375D; //375px by 375 px.
var resizeImagePath = string.Concat(path.Substring(0, path.LastIndexOf('\\')), "\\Resized");
var newImageName = path.Remove(0, path.LastIndexOf('\\') + 1);
var newImageFullPath = string.Concat(resizeImagePath, "\\", newImageName);
if (image.Width > widthAndHeightMax || image.Height > widthAndHeightMax || !File.Exists(newImageFullPath))
{
//Get Image Ratio
var ratioX = widthAndHeightMax / image.Width;
var ratioY = widthAndHeightMax / image.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
var newImage = new System.Drawing.Bitmap(newWidth, newHeight);
var resizedImage = System.Drawing.Graphics.FromImage(newImage);
resizedImage.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
resizedImage.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
resizedImage.DrawImage(image, 0, 0, newWidth, newHeight);
if (!Directory.Exists(resizeImagePath))
{
Directory.CreateDirectory(resizeImagePath);
}
// Get an ImageCodecInfo object that represents the JPEG codec.
var imageCodecInfo = ImageCodecInfo.GetImageDecoders().SingleOrDefault(c => c.FormatID == ImageFormat.Jpeg.Guid);
// Create an Encoder object for the Quality parameter.
var encoder = Encoder.Quality;
// Create an EncoderParameters object.
var encoderParameters = new EncoderParameters(1);
// Save the image as a JPEG file with quality level.
var encoderParameter = new EncoderParameter(encoder, 100L);
encoderParameters.Param[0] = encoderParameter;
//newImage.Save(newImageFullPath, imageCodecInfo, encoderParameters); throws GDI+ general error. normally security related
using (var ms = new MemoryStream())
{
try
{
using (var fs = new FileStream(string.Concat(resizeImagePath, "\\", newImageName), FileMode.Create, FileAccess.ReadWrite))
{
newImage.Save(ms, imageCodecInfo, encoderParameters);
var bytes = ms.ToArray();
fs.Write(bytes, 0, bytes.Length);
}
}
catch
{
//If the image exists, it may already be used by another process (which means it exists)
}
}
productImage = newImageFullPath;
}
}