Size of image increases after cropping - c#

I have c# code to crop images.
When i crop image (size:191 KB, using my c# code) then size of resulted (cropped) image increases (size:2.44 MB)
Please tell me why size increases after cropping ..???
Bitmap source = new Bitmap(#"F:\images\Row" + i + "Col" + j + ".jpg");
Rectangle section = new Rectangle(new Point(0, 0), new Size(1362, 761));
Bitmap CroppedImage = CropImage(source, section);
CroppedImage.Save(#"file path\Row" + i + "Col" + j + ".jpg");
public Bitmap CropImage(Bitmap source, Rectangle section)
{
// An empty bitmap which will hold the cropped image
Bitmap bmp = new Bitmap(section.Width, section.Height);
Graphics g = Graphics.FromImage(bmp);
// Draw the given area (section) of the source image
// at location 0,0 on the empty bitmap (bmp)
g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);
return bmp;
}

Telepathic power: you are talking about size of file on disk and comparing original compressed file (likely JPG) with cropped version saved in non-compressed format (likely BMP).
Fix: save cropped image in compressed format.
Image.Save with 2 arguments lets you specify format (i.e. unlike one argument version you use in your sample).
Example from the article:
// Construct a bitmap from the button image resource.
Bitmap bmp1 = new Bitmap(typeof(Button), "Button.bmp");
// Save the image as a GIF.
bmp1.Save("c:\\button.gif", System.Drawing.Imaging.ImageFormat.Gif);

Related

Converting a image to 32bpp format gives strange offset?

I have the following code:
public static Bitmap ConvertTo32bppArgb(this Image image)
{
Bitmap newBmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb);
using (Graphics gfx = Graphics.FromImage(newBmp))
{
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
gfx.DrawImage(image, 0, 0);
}
return newBmp;
}
However with some images this is giving some weird 1 pixel offset in that starts somewhere in the middle of the image. This happens with Format32bppArgb format but not with Format8bppIndexed.
What i want is that this function always returns a Bitmap that has Format32bppArgb (without that strange offset ofcourse).
Original image:
Processed image (see the tile 7th tile from the top (starts at pixel coordinates 0, 192) its 32x33 instead of 32x32)):

Cropping an image from file and resaving in C#

Never really worked with Graphics before. I have looked around on this and pieced together a few solutions from answers which address small parts of my question. but none have worked.
I want to load an image from a file, which will always be 320x240 in size. I then want to crop it to obtain a 240x240 image, with the outer 40px on each side trimmed. After this is done I want to save as a new image.
private void croptoSquare(string date)
{
//Location of 320x240 image
string fileName = Server.MapPath("~/Content/images/" + date + "contactimage.jpg");
//New rectangle of final size (I think maybe Point is where I would eventually specify where the crop square site i.e. (40, 0))
Rectangle cropRect = new Rectangle(new Point(0, 0), new Size(240, 240));
//Create a Bitmap with correct height/width.
Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
//Load image from file
using (Image image = Image.FromFile(fileName))
{
//Create Graphics object from image
using (Graphics graphic = Graphics.FromImage(image))
{
//Not sure what this does, I found it on a post.
graphic.DrawImage(image,
cropRect,
new Rectangle(0, 0, target.Width, target.Height),
GraphicsUnit.Pixel);
fileName = Server.MapPath("~/Content/images/" + date + "contactimagecropped.jpg");
image.Save(fileName);
}
}
}
Currently it is simply resaving the same image and I'm not sure why. I have specified a destination rectangle as 240x240 and a src rectangle as 320x240.
As I say I know basically nothing about working with graphics objects so I imagine this is blatant.
Can anybody tell me how to achieve what I want?
private void croptoSquare(string date)
{
//Location of 320x240 image
string fileName = Server.MapPath("~/Content/images/" + date + "contactimage.jpg");
// Create a new image at the cropped size
Bitmap cropped = new Bitmap(240,240);
//Load image from file
using (Image image = Image.FromFile(fileName))
{
// Create a Graphics object to do the drawing, *with the new bitmap as the target*
using (Graphics g = Graphics.FromImage(cropped) )
{
// Draw the desired area of the original into the graphics object
g.DrawImage(image, new Rectangle(0, 0, 240, 240), new Rectangle(40, 0, 240, 240), GraphicsUnit.Pixel);
fileName = Server.MapPath("~/Content/images/" + date + "contactimagecropped.jpg");
// Save the result
cropped.Save(fileName);
}
}
}
Why don't you use JCrop instead? http://www.programmerclubhouse.com/index.php/crop-image-using-jcrop-in-asp-net-c-shar/

Apply Curl effect to a static Image C#

Anyone ever wrote a C# GDI+ function to curl the corner of a BITMAP. I need to be able to take a static image and apply the peel effect to it on the bottom right corner. And I need to do it with C# all my searching leads to CSS3/FLASH/SilverLight virtual book type examples. I just want to create a static image that has a curled up corner and save the file.
Any Ideas?
Ok so I made the image with photo shop so that I can show you what I am trying to achieve
I start this image
and I want to write some C# code that would yield this image
The end result is just an image that is not animated, and does nothing. Any thoughts.
There are some good tools to do this, such as Fred's ImageMagick plugin script, but here is a C# version as requested.
using System.Drawing.Imaging;
public partial class ImagePeelEffect : Form
{
string WorkingDirectory = #"C:\temp\";
public ImagePeelEffect()
{
InitializeComponent();
}
private void ImagePeelEffect_Load(object sender, EventArgs e)
{
picBefore.Image = Image.FromFile(WorkingDirectory + "\\before.jpg");
}
private void button1_Click(object sender, EventArgs e)
{
//create a image object containing the photograph to add page peel effect
Image imgPhoto = Image.FromFile(WorkingDirectory + "\\before.jpg");
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;
//create a Bitmap the Size of the original photograph
Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
//load the Bitmap into a Graphics object
Graphics grPhoto = Graphics.FromImage(bmPhoto);
//create a image object containing the PagePeel
Image imgPagePeel = new Bitmap(WorkingDirectory + "\\PagePeel.bmp");
int ppWidth = imgPagePeel.Width;
int ppHeight = imgPagePeel.Height;
//Set the rendering quality for this Graphics object
grPhoto.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//Draws the photo Image object at original size to the graphics object.
grPhoto.DrawImage(
imgPhoto, // Photo Image object
new Rectangle(0, 0, phWidth, phHeight), // Rectangle structure
0, // x-coordinate of the portion of the source image to draw.
0, // y-coordinate of the portion of the source image to draw.
phWidth, // Width of the portion of the source image to draw.
phHeight, // Height of the portion of the source image to draw.
GraphicsUnit.Pixel); // Units of measure
//The first step in manipulating the PagePeel image is to replace
//the background color with one that is transparent (Alpha=0, R=0, G=0, B=0)
//to do this we will use a Colormap and define ImageAttributes with a RemapTable
ImageAttributes imageAttributes = new ImageAttributes();
ColorMap colorMap = new ColorMap();
//My PagePeel was defined with a background of 100% Green this will
//be the color we search for and replace with transparency
colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
//Set the Remap Table with the old and new color map
ColorMap[] remapTable = { colorMap };
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
//For this example we will place the PagePeel in the bottom right
//hand corner of the photograph
int xPosOfPp = phWidth - ppWidth;
int yPosOfPp = phHeight - ppHeight + 1;
grPhoto.DrawImage(imgPagePeel,
new Rectangle(xPosOfPp, yPosOfPp, ppWidth, ppHeight), //Set the detination Position
0, // x-coordinate of the portion of the source image to draw.
0, // y-coordinate of the portion of the source image to draw.
ppWidth, // PagePeel Width
ppHeight, // PagePeel Height
GraphicsUnit.Pixel, // Unit of measurment
imageAttributes); //ImageAttributes Object
//Replace the original photgraphs bitmap with the new Bitmap
imgPhoto = bmPhoto;
grPhoto.Dispose();
//save new image to file system.
imgPhoto.Save(WorkingDirectory + "\\after.jpg", ImageFormat.Jpeg);
imgPhoto.Dispose();
imgPagePeel.Dispose();
//Show the After image
picAfter.Image = Image.FromFile(WorkingDirectory + "\\after.jpg");
}
The PagePeel.bmp:
The Before and After result:
Update
Here's a version that uses a Transparent Page Peel overlay so you dont neet to convert the "green screen" to invisible. The advantage of this method is when the original photograph contains the colour green RGB(0,255,0) it wont be turned into transparent:
TransparentPagePeel.png:
private void button2_Click(object sender, EventArgs e)
{
//create a image object containing the photograph to add page peel effect
Image imgPhoto = Image.FromFile(WorkingDirectory + "\\before.jpg");
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;
//create a Bitmap the Size of the original photograph
Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
//load the Bitmap into a Graphics object
Graphics grPhoto = Graphics.FromImage(bmPhoto);
//create a image object containing the PagePeel
Image imgPagePeel = new Bitmap(WorkingDirectory + "\\transparentPagePeel.png");
int ppWidth = imgPagePeel.Width;
int ppHeight = imgPagePeel.Height;
//Set the rendering quality for this Graphics object
grPhoto.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//Draws the photo Image object at original size to the graphics object.
grPhoto.DrawImage(
imgPhoto, // Photo Image object
new Rectangle(0, 0, phWidth, phHeight), // Rectangle structure
0, // x-coordinate of the portion of the source image to draw.
0, // y-coordinate of the portion of the source image to draw.
phWidth, // Width of the portion of the source image to draw.
phHeight, // Height of the portion of the source image to draw.
GraphicsUnit.Pixel); // Units of measure
//For this example we will place the PagePeel in the bottom right
//hand corner of the photograph
int xPosOfPp = phWidth - ppWidth;
int yPosOfPp = phHeight - ppHeight + 1;
grPhoto.DrawImage(imgPagePeel,
new Rectangle(xPosOfPp, yPosOfPp, ppWidth, ppHeight), //Set the detination Position
0, // x-coordinate of the portion of the source image to draw.
0, // y-coordinate of the portion of the source image to draw.
ppWidth, // PagePeel Width
ppHeight, // PagePeel Height
GraphicsUnit.Pixel, // Unit of measurment
null); //ImageAttributes Object
//Replace the original photgraphs bitmap with the new Bitmap
imgPhoto = bmPhoto;
grPhoto.Dispose();
//save new image to file system.
imgPhoto.Save(WorkingDirectory + "\\after1.jpg", ImageFormat.Jpeg);
imgPhoto.Dispose();
imgPagePeel.Dispose();
picAfter.Image = Image.FromFile(WorkingDirectory + "\\after1.jpg");
}

convert images from python to c# - Image sizes are way too different

I am trying to convert images from python to c#, the images which python has created are much smaller in size and images which .net is creating are much larger in size. I do not want to reduce the quality of images, not sure why it is happening.
here is the python code.
if img.mode != "RGB":
img = img.convert("RGB")
img = img.resize((width,height), Image.ANTIALIAS)
resampled_image_name = os.path.splitext(resampled_image_name)[0] + "." + format
img.save(resampled_image_name)
and this is my c# code
Bitmap bitmap = new Bitmap(width, height);
using (Graphics gr = Graphics.FromImage(bitmap))
{
gr.DrawImage(srcImage, new Rectangle(0, 0, width, height));
}
FileInfo info = new FileInfo(resampledImageName);
resampledImageName = resampledImageName.Replace(info.Extension, "." + format);
bitmap.Save(#resampledImageName);

C# Creating thumbnail (low quality and big size problem)

public void CreateThumbnail(Image img1, Photo photo, string targetDirectoryThumbs)
{
int newWidth = 700;
int newHeight = 700;
double ratio = 0;
if (img1.Width > img1.Height)
{
ratio = img1.Width / (double)img1.Height;
newHeight = (int)(newHeight / ratio);
}
else
{
ratio = img1.Height / (double)img1.Width;
newWidth = (int)(newWidth / ratio);
}
Image bmp1 = img1.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
bmp1.Save(targetDirectoryThumbs + photo.PhotoID + ".jpg");
img1.Dispose();
bmp1.Dispose();
}
I've put 700px so that you can have better insight of the problem.
Here is original image and resized one.
Any good recommendation?
Thanks,
Ile
You should find my answer to this question helpful. It includes a sample for high quality image scaling in C#.
The full sample in my other answer includes how to save the image as a jpeg.
Here's the relevant bit of code...
/// <summary>
/// Resize the image to the specified width and height.
/// </summary>
/// <param name="image">The image to resize.</param>
/// <param name="width">The width to resize to.</param>
/// <param name="height">The height to resize to.</param>
/// <returns>The resized image.</returns>
public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
{
//a holder for the result
Bitmap result = new Bitmap(width, height);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the image into the target bitmap
graphics.DrawImage(image, 0, 0, result.Width, result.Height);
}
//return the resulting bitmap
return result;
}
If the image contains a thumbnail it'll automatically stretch it to the desired size...which will make it look like crap (like your case ;))
Straight outta MSDN...
If the Image contains an embedded
thumbnail image, this method retrieves
the embedded thumbnail and scales it
to the requested size. If the Image
does not contain an embedded thumbnail
image, this method creates a thumbnail
image by scaling the main image.
In your case I just double checked the source image for it's thumbnail and got this...
New Windows Thumbnail : JPEG Format (Offset:830Size:3234)
Thumbnail Type : JPEG
Thumnail Width : 112
Thumbnail Height : 84
Try to draw the original image to another smaller image, and save the result.
Bitmap bmp1 = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(bmp);
g.DrawImage(img1, 0, 0, newWidth, newHeight);
bmp1.Save(targetDirectoryThumbs + photo.PhotoID + ".jpg", ImageFormat.Jpeg);
Are you allowed to use third party applications? If so, you may want to check out ImageMagick to manage thumbnail creation. There's a .NET wrapper.
http://imagemagick.codeplex.com/
I wrote a free .dll that does this easily. It's here if you want to see the documentation....
Git Repository & Tutorial

Categories

Resources