GDI+ DrawImage function - gdi+

There is something I am missing. Say I have the following code:
private Bitmap source = new Bitmap (some_stream);
Bitmap bmp = new Bitmap(100,100);
Rectangle newRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
Rectangle toZoom= new Rectangle(0, 0, 10, 10);
Graphics g = Graphics.FromImage(bmp);
g.DrawImage(source, newRect, toZoom, GraphicsUnit.Pixel);
My goal is to zoom-in the 10x10 pixels on the top left corner of the source picture. After I created the graphics object g and called DrawImage: the requested rectangle (toZoom) will be copied to bmp, or will it be displayed on the screen? I am a bit confused, can somebody please clarify?

You code will only give you an in-memory bitmap (which won't automatically be displayed to the screen). A simple way to display this would be to put a 100 x 100 PictureBox on your form, and set its Image property like this (using the Bitmap from your code above):
pictureBox1.Image = bmp;
Also, you'll want some using blocks in your code:
using (private Bitmap source = new Bitmap (some_stream))
{
Bitmap bmp = new Bitmap(100,100);
Rectangle newRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
Rectangle toZoom= new Rectangle(0, 0, 10, 10);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, newRect, toZoom, GraphicsUnit.Pixel);
}
pictureBox1.Image = bmp;
}
Note that there is no using block with bmp - this is because you're setting it as the PictureBox's Image property. The using block automatically calls an object's Dispose method at the end of the block's scope, which you don't want to do since it will still be in use.

it will be copied and not displayed.

Related

Creating a Javafx image from a int array

I am desperately trying to create an Image from a pixel-array with integer values. Regardless of using the WritableImage or the Canvas, it is always said that the PixelFormat is BYTE_RGB or BYTE_BGRA_PRE, so that I am forced to use a byte-array.
Is there any way to change the PixelFormat to <IntBuffer> or did I overlook another component that is capable of having a PixelFormat<IntBuffer>?
You haven't described the structure of the pixel data in your int[], but you can do something along the lines of
int[] pixels = ... ;
WritableImage img = new WritableImage(width, height);
PixelWriter pw = img.getPixelWriter();
pw.setPixels(0, 0, width, height, PixelFormat.getIntArgbInstance(), pixels, 0, width);

Asp.net image resizing quality

I have this code that I use to resize and save a file that is posted by the user.
The issue is that when I rezise to a 480px width the image looses lots of quality and the size in kb is still pretty big.
For instance, when I resize the same image to 480px "by hand" using a software like Paint, the quality is still as good as the original (from what my eye can tell) and the size in kb is a lot smaller than resizing using the GetThumbNailImage method.
Mdn says "If you request a large thumbnail image (for example, 300 x 300) from an Image that has an embedded thumbnail, there could be a noticeable loss of quality in the thumbnail image. It might be better to scale the main image (instead of scaling the embedded thumbnail) by calling the DrawImage method.", but that seems to be for Windows forms and I need for a web app.
What code should I use to do this then?
System.IO.Stream st = FileUploadPost.PostedFile.InputStream;
myImage = System.Drawing.Image.FromStream(st);
thumb = myImage.GetThumbnailImage(newWidth, newHeight, null, System.IntPtr.Zero);
thumb.Save(myPath);
Here is code that has worked for me. You can set the new bitmap resolution:
using System.Drawing;
Bitmap img = (Bitmap)Bitmap.FromStream(FileUploadPost.PostedFile.InputStream);
Bitmap newImg = new Bitmap(maxWidth, maxHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
newImg.SetResolution(72, 72);
Graphics newGraphic = Graphics.FromImage(newImg);
newGraphic.Clear(Color.Transparent);
newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
newGraphic.DrawImage(img, 0, 0, maxWidth, maxHeight);
System.Drawing.Imaging.ImageFormat format = default(System.Drawing.Imaging.ImageFormat);
string ext = Path.GetExtension(FileUploadPost.PostedFile.FileName);
switch (ext.ToLower())
{
case ".gif":
format = System.Drawing.Imaging.ImageFormat.Gif;
break;
case ".png":
format = System.Drawing.Imaging.ImageFormat.Png;
break;
default:
format = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
}
newImg.Save(myPath, format);
You can wrap it in a void function on a global class:
public static void UploadImage(HttpPostedFileBase file, int maxWidth, int maxHeight)
{
//paste all the above code in here and replace FileUploadPost.PostedFile with file
}
Then you can call it from anywhere in your project:
ClassName.UploadImage(FileUploadPost.PostedFile, 300, 300);
Does this answer sufficiently?
Resizing an image in asp.net without losing the image quality
This is an issue that comes up fairly frequently.
Try this
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
public static System.Drawing.Image ResizeImage( System.Drawing.Image image, int percent ) {
// percent is the actual integer percent of the original size
System.Drawing.Bitmap imgThumb = new System.Drawing.Bitmap( image.Width * percent / 100, image.Height * percent / 100 );
Rectangle sourceRect = new Rectangle( 0, 0, image.Width, image.Height );
Rectangle destRect = new Rectangle( 0, 0, imgThumb.Width, imgThumb.Height );
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage( imgThumb );
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage( image, destRect, sourceRect, GraphicsUnit.Pixel );
return ( imgThumb );
}

conversion from quickdraw to quartz 2D

I have an old code that uses,
Rect r;
GetPortBounds(some_bitmap,&r);
PixMapHandle somehandle = GetGWorldPixMap(some_bitmap);
if(LockPixels(somehandle)){
TPixel *data = (TPixel *) GetPixBaseAddr(somehandle);
long row_bytes = GetPixRowBytes(somehandle);
// doing something
UnlockPixels(somehandle);
}
Can anyone help me with the replacement code in quartz 2d
To modify a bitmap with Quartz you can initialize a CGContextRef with the image and draw to that context with CGContextDraw... routines.
(I wrote the following sample code for a NSView subclass. It's a bit inefficient. If you use the code, separate the stuff you can keep around in iVars.)
- (void)drawRect:(NSRect)dirtyRect
{
//Load an image ...
NSImage* image = [[NSImage alloc] initWithContentsOfFile:#"/Library/Desktop Pictures/Grass Blades.jpg"];
CGImageRef testImage = [[[image representations] objectAtIndex:0] CGImage];
[image release];
CGDataProviderRef dataProvider = CGImageGetDataProvider(testImage);
//... and retrieve its pixel data
CFDataRef imageData = CGDataProviderCopyData(dataProvider);
void* pixels = (void*)CFDataGetBytePtr(imageData);
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
//Init a quartz context that uses the pixel data memory as buffer
CGContextRef drawContext = CGBitmapContextCreate(pixels, CGImageGetWidth(testImage), CGImageGetHeight(testImage), CGImageGetBitsPerComponent(testImage), CGImageGetBytesPerRow(testImage), colorspace, CGImageGetBitmapInfo(testImage));
CGContextSetRGBFillColor(drawContext, 0.8, 0.8, 0.8, 1.0);
//Do something with the newly created context
CGContextFillRect(drawContext, CGRectMake(20.0, 20.0, 200.0, 200.0));
CGColorSpaceRelease(colorspace);
CGImageRef finalImage = CGBitmapContextCreateImage(drawContext);
//Draw the modified image to the screen
CGContextDrawImage([[NSGraphicsContext currentContext] graphicsPort], dirtyRect, finalImage);
CFRelease(imageData);
CGImageRelease(finalImage);
CGContextRelease(drawContext);
}

.net Drawing.Graphics.FromImage() returns blank black image

I'm trying to rescale uploaded jpeg in asp.net
So I go:
Image original = Image.FromStream(myPostedFile.InputStream);
int w=original.Width, h=original.Height;
using(Graphics g = Graphics.FromImage(original))
{
g.ScaleTransform(0.5f, 0.5f); ... // e.g.
using (Bitmap done = new Bitmap(w, h, g))
{
done.Save( Server.MapPath(saveas), ImageFormat.Jpeg );
//saves blank black, though with correct width and height
}
}
this saves a virgin black jpeg whatever file i give it.
Though if i take input image stream immediately into done bitmap, it does recompress and save it fine, like:
Image original = Image.FromStream(myPostedFile.InputStream);
using (Bitmap done = new Bitmap(original))
{
done.Save( Server.MapPath(saveas), ImageFormat.Jpeg );
}
Do i have to make some magic with g?
upd:
i tried:
Image original = Image.FromStream(fstream);
int w=original.Width, h=original.Height;
using(Bitmap b = new Bitmap(original)) //also tried new Bitmap(w,h)
using (Graphics g = Graphics.FromImage(b))
{
g.DrawImage(original, 0, 0, w, h); //also tried g.DrawImage(b, 0, 0, w, h)
using (Bitmap done = new Bitmap(w, h, g))
{
done.Save( Server.MapPath(saveas), ImageFormat.Jpeg );
}
}
same story - pure black of correct dimensions
Since you didn't fill the area with background of image you're reading from inputStream,you can only get a blank image that way.
Instead of using scaling the image,you can use Fill background into a resized area.
Check this out:
Image img = Image.FromFile(Server.MapPath("a.png"));
int w = img.Width;
int h = img.Height;
//Create an empty bitmap with scaled size,here half
Bitmap bmp = new Bitmap(w / 2, h / 2);
//Create graphics object to draw
Graphics g = Graphics.FromImage(bmp);
//You can also use SmoothingMode,CompositingMode and CompositingQuality
//of Graphics object to preserve saving options for new image.
//Create drawing area with a rectangle
Rectangle drect = new Rectangle(0, 0, bmp.Width, bmp.Height);
//Draw image into your rectangle area
g.DrawImage(img, drect);
//Save your new image
bmp.Save(Server.MapPath("a2.jpg"), ImageFormat.Jpeg);
Hope this helps
Myra
Try this:
- get the Image from your stream
- create a new Bitmap of the correct size
- get the Graphics object from the new bitmap, not the original one
- call g.DrawImage(original, 0, 0, done.Width, done.Height)
Edit:
The problem is this section:
using (Bitmap done = new Bitmap(w, h, g))
{
done.Save( Server.MapPath(saveas), ImageFormat.Jpeg );
}
You're creating a black bitmap, with the resolution specified by g. You're not actually creating a bitmap with any image data coming from g. In fact, I don't think the Graphics object actually stores image data that you can really pass around, it just allows you to manipulate some object that stores the image data.
Try replacing that with b.Save(...)

to crop a image by selecting part of imageusing ActionScript3.0 and Flex3.0

To crop the image into a selected size by drawing rectangle over it. It should be done in ActionScript 3.0 and Flex 3.0
warm rgds,
You can use BitmapData.copyPixels() for this.
//create a rectangle
var cropRect:Rectangle = new Rectangle(left, top, width, height);
//create new bitmap data - because BitmapData's width/height are read only
var bmpData:BitmapData = new BitmapData(cropRect.width, cropRect.height, true);
bmpData.copyPixels(image.bitmapData, cropRect, new Point(0, 0));
//assign the cropped bitmap data to the image.
image.bitmapData = bmpData;
copyPixels() method
public function copyPixels(sourceBitmapData:BitmapData, sourceRect:Rectangle,
destPoint:Point, alphaBitmapData:BitmapData = null, alphaPoint:Point = null,
mergeAlpha:Boolean = false):void
Provides a fast routine to perform pixel manipulation between images with no stretching, rotation, or color effects. This method copies a rectangular area of a source image to a rectangular area of the same size at the destination point of the destination BitmapData object.

Resources