I want store the image in SQL server table, and I successed but when I retrive that image on page, I found that the image has lost its transparency. The origional image is png/gif. I have resized that image in 100px / 100px.
I have used following code to resixe the image. It works but when it stores image in database it lost the transparency.
using (System.Drawing.Image oldImage = System.Drawing.Image.FromStream(new MemoryStream(imageFile)))
{
System.Drawing.Size newSize = CalculateDimensions(oldImage.Size, targetSize);
using (System.Drawing.Bitmap newImage = new System.Drawing.Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb))
{
using (System.Drawing.Graphics canvas = System.Drawing.Graphics.FromImage(newImage))
{
canvas.Clear(System.Drawing.Color.Transparent);
canvas.SmoothingMode = SmoothingMode.HighQuality;
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
canvas.DrawImage(oldImage, new System.Drawing.Rectangle(new System.Drawing.Point(0, 0), newSize));
MemoryStream m = new MemoryStream();
newImage.Save(m, ImageFormat.Png);
return m.GetBuffer();
}
}
}
Any solution????
Thanks
This one probably answers your question:
Why does resizing a png image lose transparency?
As the above link suggests, you're not loosing transparency because the image is saved into the database. It's when you resize the image that the transparency is lost.
Related
Is there a quick way using System.Drawing to quickly enlarge the image canvas of an .png image? (see example below). The caveat is the background might be transparent and I want to keep it transparent.
Edit: Needs to be in ASP .Net CORE
Alternatively, is there a way of putting the image on a white background that is slightly larger than the image?
After a few days of trial and error, I think I found something that works
Image overlayImage = //get your image here from file or url.
xloc = //x coord where to start overlay image.
yloc = //y coord where to start overlay image.
canvasWidth = //width of background canvas
canvasHeight = //height of background canvas
Bitmap baseImage = new Bitmap(canvasWidth, canvasHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
using (Graphics graphics = Graphics.FromImage(baseImage))
{
using (System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.White))
{
graphics.FillRectangle(myBrush, new Rectangle(0, 0, canvasWidth, canvasHeight)); // white rectangle
}
graphics.CompositingMode = CompositingMode.SourceOver;
graphics.DrawImage(overlayImage, xloc, yloc);
} // graphics will be disposed at this line
Working on allowing the upload of images which can range in a variety of size, then allowing to crop a predefined area of the image for a thumbnail.
The thumbnail size is predefined to 150x150. Using the Jcrop.js tool to select a section of the image.
Problem:
When displaying the uploaded image in a smaller size than the original image by implementing set height/width on the image rendered, then there is a scale factor that comes into play when selecting an area to crop.
You either have to scale down the cropping area proportionately or you have to scale the image in relation to the actual image's size in comparison to its displayed size.
Question:
How do I figure out the scale of the browser displayed image vs. original image? I am currently using the following code to save the image, but how would I take into consideration the scaling?
public static Image CropImage(Image originalImage, int x, int y, int width, int height)
{
var bmp = new Bitmap(width, height);
bmp.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);
using (var graphic = Graphics.FromImage(bmp))
{
graphic.SmoothingMode = SmoothingMode.AntiAlias;
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.PixelOffsetMode = PixelOffsetMode.HighSpeed;
graphic.DrawImage(originalImage, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel);
return bmp;
}
}
Bonus Question:
Another problem I discovered, is that there seems to be no efficient way to transfer the original file's ImageFormat when creating a new Bitmap which creates a ImageFormatMemoryBMP and when you attempt to call Bitmap.Save(memorystream, original rawformat) it will blow up. And bitmap RawFormat has no setter.
So how can you set the format on a new bitmap?
I think perhaps that this problem is solved purely on the front end, no need to use any server side for this.
Jcrop has a built in scale factor handler.
http://deepliquid.com/content/Jcrop_Sizing_Issues.html
Now you can use this in two ways, as I understand it. Either to 'resize' the image for you on the front end using 'box sizing', or you can tell it the 'truesize' of the image and it will work out the scale factor and handle the coordinates for you on it's own.
Box sizing
$('#cropbox').Jcrop({ boxWidth: 450, boxHeight: 400 });
True Size
$.Jcrop('#cropbox',{ trueSize: [500,370] });
Using the true size method you will need to invoke jcrop using the api method:
http://deepliquid.com/content/Jcrop_API.html#API_Invocation_Method
var jcrop_api,
options = { trueSize: [500,370] };
$('#target').Jcrop(options,function(){
jcrop_api = this;
});
Good luck!
I want to render some text as image in ASP.NET. It is working well, but the text is rendered very ugly (with grey pixels around the text) even if I turn on AntiAlias (or ClearType) by changing the graphics TextRenderingHint option.
Here is the relevant code:
float width;
float height;
System.Drawing.Text.PrivateFontCollection fontcollection = new System.Drawing.Text.PrivateFontCollection();
// Add the custom font families
fontcollection.AddFontFile(Server.MapPath("./Fonts/" + fontfile));
Bitmap image = new Bitmap(10, 10);
Graphics graphic = Graphics.FromImage(image);
Font font = new Font(fontcollection.Families.First(), fontsize, style);
SizeF size = graphic.MeasureString(text, font);
width = size.Width;
height = size.Height;
image = new Bitmap(Convert.ToInt32(width), Convert.ToInt32(height));
graphic = Graphics.FromImage(image);
graphic.FillRectangle(new SolidBrush(Color.White), 0, 0, width, height);
graphic.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bicubic;
graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
graphic.DrawString(text, font, Brushes.Black, new PointF(0, 0));
Response.ContentType = "image/jpeg";
image.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
Here a link to the generated image (zoom):
Unzoomed image:
How can I solve this?
Make the imageformat PNG.
The default JPEG compression is useless.
I have a game with a big raster map
Now we are using jpeg (4900x4200)
And durring the game we need to scroll through this map.
We use the following:
Class Map extends mx.containers.Canvas
and mx.controls.Image on it
In constructor we have:
public function Map() {
super();
image.source = ResourceManager.interactiveManager.map;//big image
addChild(image);
......
}
for scrolling we are use:
if(parentAsCanvas==null){
parentAsCanvas = (parent as Canvas);
}
parentAsCanvas.verticalScrollPosition = newX;
parentAsCanvas.horizontalScrollPosition = newY;
In windows, we have very good performance.
In Linux and Mac in flashplayer we have a good performance too.
But in browsers performance is quite slow!
What can we do to resolve it?
It's slow because you're rendering a large image all the time.
Here are a few things that cross my mind:
Try using the scrollRect property in a Bimtap object holding your image BitmapData to display just the visible area then use the scrollRect x and y to move to a new region
Try using a BitmapData the size of the viewable area and use copyPixels() to get the right area to display, again using a rectangle
Try using BitmapData.scroll()
Here are a few snippets:
scrollRect:
//assuming map is BitmapData containing your large image
//100x100 is a test scroll area
var scroll:Rectangle = new Rectangle(0,0,100,100);
var bitmap:Bitmap = new Bitmap(map);
bitmap.scrollRect = scroll;
addChild(bitmap);
this.addEventListener(Event.ENTER_FRAME, update);
function update(event:Event):void{
scroll.x = mouseX;
scroll.y = mouseY;
bitmap.scrollRect = scroll;
}
copyPixels:
var scroll:Rectangle = new Rectangle(0,0,100,100);
var scrollPoint:Point = new Point();
var map:BitmapData = new Map(0,0);
var bitmap:Bitmap = new Bitmap(new BitmapData(100,100,false));
bitmap.bitmapData.copyPixels(map,scroll,scrollPoint);
addChild(bitmap);
this.addEventListener(Event.ENTER_FRAME, update);
function update(event:Event):void{
scroll.x = mouseX;
scroll.y = mouseY;
bitmap.bitmapData.fillRect(scroll,0xFFFFFF);
bitmap.bitmapData.copyPixels(map,scroll,scrollPoint);
}
Not perfect, but it should give you an idea
HTH,
George
I've read the following acrticle http://www.insideria.com/2008/04/flex-ria-performance-considera.html
I and i found the resolve of my problem.
If i open my SWF in browser as "http://host/myswf.swf" I have huge performance lose in browser as the reason work LaoyoutManager, that recalculates positions and sizes of all canvases in the application. And it process eats more than 60% of performance capacity.(Yep, we have a lot of Canvases in our application).
And when i putted my application in contant-size html block in html page, all problems were go away! I've got 80% performance increase!
I am trying to display a bytearray as a resized image. The Image is displaying correctly, but the sizing is off. Let me explain.
First I have the image data encoded so I need to decode the image data
// Instantiate decoder
var decoder:Base64Decoder = new Base64Decoder();
// Decode image data
decoded.decode(picture.data);
// Export data as a byteArray
var byteArray:ByteArray = decoder.toByteArray();
// Display image
var img:Image = new Image();
img.load(byteArray);
This works. The image is displayed correctly. However, if I hardcode the image (img) height the resized image is shown correctly, but within a box with the original image's dimensions.
For example, if the original image has a height of 300px and a width of 200px and the img.height property is set to 75; the resized image with height of 75 is shown correctly. But the resized image is shown in the upper left corner of the img container that is still set to a height of 300px and a width of 200px. Why does it do that? And what is the fix?
The best way to illustrate the problem is by placing the image inside a VBox and show the borders of the VBox. From the code block above, if I change the image height and set the image to maintain aspect ratio (which by default is set to true but I add it here for completeness). the problem becomes clear.
// Display image
var img:Image = new Image();
img.height = 75; // Hardcode image height (thumbnail)
img.maintainAspectRatio = true;
img.load(byteArray);
// Encapsulate the image inside a VBox to illustrate the problem
var vb:VBox = new VBox();
vb.setStyle('borderStyle', 'solid');
vb.setStyle('borderColor', 'red');
vb.setStyle('borderThickness', 2);
vb.addChild(img);
I have been working on this problem for days and cannot come up with a solution. Any ideas? What am I missing?
The workaround I used is as follows:
I created an event listener for the img display object. Then after the img has loaded, I manually set the height and width of the image. I know what I want the height (preHeight) to be so that is hardcoded. I then calculate the width and set that as the image width. For some reason I had to use the explicitHeight and explicitWidth properties to finally get the sizing right.
I hope this helps someone.
img.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
private function onCreationComplete(event:FlexEvent) : void
{
img.addEventListener(Event.COMPLETE, onImageLoadComplete);
}
private function onImageLoadComplete(event:Event) : void
{
var image:Image = event.currentTarget as Image;
var preHeight:Number = 0;
var h:uint = Bitmap(image.content).bitmapData.height;
var w:uint = Bitmap(image.content).bitmapData.width;
// Check height
preHeight = h > 170 ? 170 : h;
// Set the width
img.explicitWidth = (preHeight * w)/h;
img.explicitHeight = preHeight;
}