I have a folder with images and i would like to delete some of the images by size. Unfortunately, i can’t use the File.Delete(string) method. What should I do to fix this error?
string pathName = #"C:\Users\Desktop\Images\";
DirectoryInfo dir_info = new DirectoryInfo(pathName);
foreach (FileInfo filo in dir_info.GetFiles())
{
Bitmap img = new Bitmap(filo.FullName);
int width = img.Width;
int height = img.Height;
int H = 90;
int W = 136;
if ((height >= H) && (width >= W))
{
File.Delete(filo.FullName);
}
}
Related
I'd like to figure out how I can add a 1 pixel border in between each frame that my spritesheet creator generates, can anyone help?
The function below takes an array of images and turns them into a table filled with bitmaps.
The program is supposed to take a gif and turn it into multiple spritesheets, so that it can be displayed in a game engine. That part is working fine, but I'd like to add a 1 pixel border in between each frame.
public Bitmap[] combineFrames(Image[] images, int columns)
{
int rows = columns;
int imagesPerSheet = rows * columns;
int sheets = (int)Math.Ceiling((double)images.Length / imagesPerSheet);
Bitmap[] mapTable = new Bitmap[55]; //55 being the max #sheets
for (int x = 0; x < sheets; x++)
{
Bitmap bitmap = new Bitmap(images[0].Width * columns, images[0].Height * rows);
Graphics graphics = Graphics.FromImage(bitmap);
int L = 0;
int remainingNFrames = (images.Length - (imagesPerSheet * x));
if (remainingNFrames < imagesPerSheet)
{
L = remainingNFrames;
}
else
{
L = imagesPerSheet;
}
for (int i = 0; i <= L; i++)
{
int formulizedProduct = imagesPerSheet * (x) + (i);
if (formulizedProduct == images.Length) { break; } //should always be length - 1
Image image = images[formulizedProduct]; //16*x+i
int X = (image.Width * ((i - 1) % columns));
int Y = (image.Height * (int)((double)(i - 1) / columns));
graphics.DrawImage(
image,
X, //I feel like I'd have to adjust this part and the part below, but I'm not really sure.
Y
);
}
mapTable[x] = bitmap;
}
return mapTable;
}
Thanks.
I want to Send Arabic text as Bitmap to a POS printer since I could not print Arabic words directly to the printer. I used below code to convert a text to Bitmap :
Convert_ValueToImage("كيكه", "Simplified Arabic Fixed", 12)
public static Bitmap Convert_ValueToImage(string ValueText, string Fontname, int Fontsize)
{
//creating bitmap image
Bitmap ValueBitmap = new Bitmap(1, 1);
//FromImage method creates a new Graphics from the specified Image.
Graphics Graphics = Graphics.FromImage(ValueBitmap);
// Create the Font object for the image text drawing.
Font Font = new Font(Fontname, Fontsize);
// Instantiating object of Bitmap image again with the correct size for the text and font.
SizeF stringSize = Graphics.MeasureString(ValueText, Font);
ValueBitmap = new Bitmap(ValueBitmap, (int)stringSize.Width, (int)stringSize.Height);
Graphics = Graphics.FromImage(ValueBitmap);
//Draw Specified text with specified format
Graphics.DrawString(ValueText, Font, Brushes.Black, 0, 0);
Font.Dispose();
Graphics.Flush();
Graphics.Dispose();
return ValueBitmap; //return Bitmap Image
}
and when I assign it to pictureBox it works.
Now I want to send it to the printer. I used below method to convert the bitmap image to string with adding the image mode to the string:
public string GetArabic(Bitmap ArabicText)
{
string logo = "";
BitmapData data = GetArabicBitmapData(ArabicText);
BitArray dots = data.Dots;
byte[] width = BitConverter.GetBytes(data.Width);
int offset = 0;
MemoryStream stream = new MemoryStream();
BinaryWriter bw = new BinaryWriter(stream);
bw.Write((char)0x1B);
bw.Write('#');
bw.Write((char)0x1B);
bw.Write('3');
bw.Write((byte)24);
while (offset < data.Height)
{
bw.Write((char)0x1B);
bw.Write('*'); // bit-image mode
bw.Write((byte)33); // 24-dot double-density
bw.Write(width[0]); // width low byte
bw.Write(width[1]); // width high byte
for (int x = 0; x < data.Width; ++x)
{
for (int k = 0; k < 3; ++k)
{
byte slice = 0;
for (int b = 0; b < 8; ++b)
{
int y = (((offset / 8) + k) * 8) + b;
// Calculate the location of the pixel we want in the bit array.
// It'll be at (y * width) + x.
int i = (y * data.Width) + x;
// If the image is shorter than 24 dots, pad with zero.
bool v = false;
if (i < dots.Length)
{
v = dots[i];
}
slice |= (byte)((v ? 1 : 0) << (7 - b));
}
bw.Write(slice);
}
}
offset += 24;
bw.Write((char)0x0A);
}
// Restore the line spacing to the default of 30 dots.
bw.Write((char)0x1B);
bw.Write('3');
bw.Write((byte)30);
bw.Flush();
byte[] bytes = stream.ToArray();
return logo + Encoding.Default.GetString(bytes);
}
public BitmapData GetArabicBitmapData(Bitmap bmpFileName)
{
using (var bitmap = bmpFileName )
{
var threshold = 127;
var index = 0;
double multiplier = 570; // this depends on your printer model. for Beiyang you should use 1000
double scale = (double)(multiplier / (double)bitmap.Width);
int xheight = (int)(bitmap.Height * scale);
int xwidth = (int)(bitmap.Width * scale);
var dimensions = xwidth * xheight;
var dots = new BitArray(dimensions);
for (var y = 0; y < xheight; y++)
{
for (var x = 0; x < xwidth; x++)
{
var _x = (int)(x / scale);
var _y = (int)(y / scale);
var color = bitmap.GetPixel(_x, _y);
var luminance = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
dots[index] = (luminance < threshold);
index++;
}
}
return new BitmapData()
{
Dots = dots,
Height = (int)(bitmap.Height * scale),
Width = (int)(bitmap.Width * scale)
};
}
}
this code print a black Rectangle. what would help me is if I could print the text with white background and the size is small as the text size.
I am working on my Project in Windows Forms and I have a Problem. In this Project I have to Compare Screenshot with Images from File. I have good Method for Comparison in Internet found and it seems to be working. For example: I have cuted Facebook Logo from site and saved it on Desktop. When I am comparing this Logo with itself(I am making a screenshot of a logo and than compare this screenshot with Logo) this method works correctly(it says that screenshot contains Logo) but when I am making a Screenshot on it's Site and than compare it with Logo, This Method says that Screenshot donn't contains Logo.
I am using this Compare Method:
public static Rectangle searchBitmap(Bitmap smallBmp, Bitmap bigBmp, double tolerance)
{
BitmapData smallData =
smallBmp.LockBits(new Rectangle(0, 0, smallBmp.Width, smallBmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData bigData =
bigBmp.LockBits(new Rectangle(0, 0, bigBmp.Width, bigBmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
int smallStride = smallData.Stride;
int bigStride = bigData.Stride;
int bigWidth = bigBmp.Width;
int bigHeight = bigBmp.Height - smallBmp.Height + 1;
int smallWidth = smallBmp.Width * 3;
int smallHeight = smallBmp.Height;
Rectangle location = Rectangle.Empty;
int margin = Convert.ToInt32(255.0 * tolerance);
unsafe
{
byte* pSmall = (byte*)(void*)smallData.Scan0;
byte* pBig = (byte*)(void*)bigData.Scan0;
int smallOffset = smallStride - smallBmp.Width * 3;
int bigOffset = bigStride - bigBmp.Width * 3;
bool matchFound = true;
for (int y = 0; y < bigHeight; y++)
{
for (int x = 0; x < bigWidth; x++)
{
byte* pBigBackup = pBig;
byte* pSmallBackup = pSmall;
//Look for the small picture.
for (int i = 0; i < smallHeight; i++)
{
int j = 0;
matchFound = true;
for (j = 0; j < smallWidth; j++)
{
//With tolerance: pSmall value should be between margins.
int inf = pBig[0] - margin;
int sup = pBig[0] + margin;
if (sup < pSmall[0] || inf > pSmall[0])
{
matchFound = false;
break;
}
pBig++;
pSmall++;
}
if (!matchFound) break;
//We restore the pointers.
pSmall = pSmallBackup;
pBig = pBigBackup;
//Next rows of the small and big pictures.
pSmall += smallStride * (1 + i);
pBig += bigStride * (1 + i);
}
//If match found, we return.
if (matchFound)
{
location.X = x;
location.Y = y;
location.Width = smallBmp.Width;
location.Height = smallBmp.Height;
break;
}
//If no match found, we restore the pointers and continue.
else
{
pBig = pBigBackup;
pSmall = pSmallBackup;
pBig += 3;
}
}
if (matchFound) break;
pBig += bigOffset;
}
}
bigBmp.UnlockBits(bigData);
smallBmp.UnlockBits(smallData);
return location;
}
This method returns a Rectangle "location". If (location.Width == 0 || location.height == 0), it means that Screenshot doesn't contain Image.
What's the problem?
If the screenshot contains any blank space around the border, it will most likely not match with the image (unless the screenshot is the whole screen).
the sample panorama image url https://upload.wikimedia.org/wikipedia/commons/3/3b/360%C2%B0_Hoher_Freschen_Panorama_2.jpg which i saved in my pc and generate tile from that image programmatically and got
error like out of memory
this line throw the error Bitmap bmLevelSource =
(Bitmap)Bitmap.FromFile(levelSourceImage);
here is my program code in c# which throw the error
double maxZoom = 5;
string FILEPATH = #"C:\test\img.jpg";
string TARGETFOLDER = #"C:\test\Src";
bool REMOVEXISTINGFILES = true;
if (!System.IO.File.Exists(FILEPATH))
{
Console.WriteLine("file not exist");
return;
}
if (maxZoom >= 10)
{
Console.WriteLine("Scale multiplier should be an integer <=10");
return;
}
//Read image
Bitmap bmSource;
try
{
bmSource = (Bitmap)Bitmap.FromFile(FILEPATH);
}
catch
{
Console.WriteLine("image file not valid");
return;
}
//check directory exist
if (!System.IO.Directory.Exists(TARGETFOLDER))
{
System.IO.Directory.CreateDirectory(TARGETFOLDER);
}
else if (REMOVEXISTINGFILES)
{
string[] files = System.IO.Directory.GetFiles(TARGETFOLDER);
foreach (string file in files)
System.IO.File.Delete(file);
string[] dirs = System.IO.Directory.GetDirectories(TARGETFOLDER);
foreach (string dir in dirs)
System.IO.Directory.Delete(dir, true);
}
int actualHeight = bmSource.Height;
int actualWidth = bmSource.Width;
if (((actualHeight % 256) != 0)
||
((actualWidth % 256) != 0))
{
Console.WriteLine("image width and height pixels should be multiples of 256");
return;
}
int actualResizeSizeWidth = 1;
int level = 0;
while (level <= maxZoom)
{
string leveldirectory = System.IO.Path.Combine(TARGETFOLDER, String.Format("{0}", level));
if (!System.IO.Directory.Exists(leveldirectory))
System.IO.Directory.CreateDirectory(leveldirectory);
int rowsInLevel = Convert.ToInt32(Math.Pow(2, level));
actualResizeSizeWidth = 256 * rowsInLevel;
//create image to parse
int actualResizeSizeHeight = (actualHeight * actualResizeSizeWidth) / actualWidth;
Bitmap resized = new Bitmap(bmSource, new Size(actualResizeSizeWidth, actualResizeSizeHeight));
string levelSourceImage = System.IO.Path.Combine(leveldirectory, "level.png");
resized.Save(levelSourceImage);
for (int x = 0; x < rowsInLevel; x++)
{
string levelrowdirectory = System.IO.Path.Combine(leveldirectory, String.Format("{0}", x));
if (!System.IO.Directory.Exists(levelrowdirectory))
System.IO.Directory.CreateDirectory(levelrowdirectory);
Bitmap bmLevelSource = (Bitmap)Bitmap.FromFile(levelSourceImage);
//generate tiles
int numberTilesHeight = Convert.ToInt32(Math.Ceiling(actualResizeSizeHeight / 256.0));
for (int y = 0; y < numberTilesHeight; y++)
{
Console.WriteLine("Generating Tiles " + level.ToString() + " " + x.ToString() + " " + y.ToString()); int heightToCrop = actualResizeSizeHeight >= 256 ? 256 : actualResizeSizeHeight;
Rectangle destRect = new Rectangle(x * 256, y * 256, 256, heightToCrop);
//croped
Bitmap bmTile = bmLevelSource.Clone(destRect, System.Drawing.Imaging.PixelFormat.DontCare);
//full tile
Bitmap bmFullTile = new Bitmap(256, 256);
Graphics gfx = Graphics.FromImage(bmFullTile);
gfx.DrawImageUnscaled(bmTile, 0, 0);
bmFullTile.Save(System.IO.Path.Combine(levelrowdirectory, String.Format("{0}.png", y)));
bmFullTile.Dispose();
bmTile.Dispose();
}
}
level++;
}
i comment the below code when i run the program
if (((actualHeight % 256) != 0)
||
((actualWidth % 256) != 0))
{
Console.WriteLine("image width and height pixels should be multiples of 256");
return;
}
what is the fault for which i got the error called "Out of Memory"
Thanks
Edit
actual image height and width was 1250 and 2500.
actualResizeSizeWidth 256
actualResizeSizeHeight 128
i include a panorama image url in this post at top. can u plzz download url and execute my code at your end to see memory issue is coming?
Code Update
i modify the code a bit and dispose some Bitmap.
dispose like this way
bmLevelSource.Dispose(); and resized.Dispose();
while (level <= maxZoom)
{
string leveldirectory = System.IO.Path.Combine(TARGETFOLDER, String.Format("{0}", level));
if (!System.IO.Directory.Exists(leveldirectory))
System.IO.Directory.CreateDirectory(leveldirectory);
int rowsInLevel = Convert.ToInt32(Math.Pow(2, level));
actualResizeSizeWidth = 256 * rowsInLevel;
//create image to parse
int actualResizeSizeHeight = (actualHeight * actualResizeSizeWidth) / actualWidth;
Bitmap resized = new Bitmap(bmSource, new Size(actualResizeSizeWidth, actualResizeSizeHeight));
string levelSourceImage = System.IO.Path.Combine(leveldirectory, "level.png");
resized.Save(levelSourceImage);
for (int x = 0; x < rowsInLevel; x++)
{
string levelrowdirectory = System.IO.Path.Combine(leveldirectory, String.Format("{0}", x));
if (!System.IO.Directory.Exists(levelrowdirectory))
System.IO.Directory.CreateDirectory(levelrowdirectory);
Bitmap bmLevelSource = (Bitmap)Bitmap.FromFile(levelSourceImage);
//generate tiles
int numberTilesHeight = Convert.ToInt32(Math.Ceiling(actualResizeSizeHeight / 256.0));
for (int y = 0; y < numberTilesHeight; y++)
{
Console.WriteLine("Generating Tiles " + level.ToString() + " " + x.ToString() + " " + y.ToString()); int heightToCrop = actualResizeSizeHeight >= 256 ? 256 : actualResizeSizeHeight;
Rectangle destRect = new Rectangle(x * 256, y * 256, 256, heightToCrop);
//croped
Bitmap bmTile = bmLevelSource.Clone(destRect, System.Drawing.Imaging.PixelFormat.DontCare);
//full tile
Bitmap bmFullTile = new Bitmap(256, 256);
Graphics gfx = Graphics.FromImage(bmFullTile);
gfx.DrawImageUnscaled(bmTile, 0, 0);
bmFullTile.Save(System.IO.Path.Combine(levelrowdirectory, String.Format("{0}.png", y)));
bmFullTile.Dispose();
bmTile.Dispose();
}
bmLevelSource.Dispose();
}
level++;
resized.Dispose();
}
please see my bit modified code and give suggestion now.
Basically, I have an image which could be large (couple of thousand pixels in both height and width), and can vary quite a bit in width's and height's.
What I need to do is display these images at approximately 500 pixels in height and width - but I want to keep the aspect ratio of these intact, so the values would just be fairly close. But I'm a bit confused on what calculations I could use on the original width's and heights to get them to the right figures.
Any ideas?
Try this:
Size original = new Size(5000,4000);
double ratio = (double)original.Height/original.Width;
int resizePercent = 50;
int newWidth = Convert.ToInt32(original.Width*resizePercent/100);
int newHeight = Convert.ToInt32(newWidth * ratio);
Size resized = new Size(newWidth,newHeight);
Of course simply set original variable to your images size and determine your resize percentage. You could calculate the resize percentage if you had a target width like this:
int targetWidth = 500;
int resizePercent = Convert.ToInt32((double)original.Width/targetWidth);
I ran into this problem a couple weeks ago. Check out this article https://web.archive.org/web/20200508200042/http://www.4guysfromrolla.com:80/articles/012203-1.2.aspx
You create a Generic Handler (.ashx) that finds the image, resizes it, and returns it
Here is what I ended up using (you can resize on the fly):
public void ProcessRequest (HttpContext context) {
TimeSpan refresh = new TimeSpan(168, 0, 0);
HttpContext.Current.Response.Cache.SetExpires(DateTime.Now.Add(refresh));
HttpContext.Current.Response.Cache.SetMaxAge(refresh);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
HttpContext.Current.Response.Cache.SetValidUntilExpires(true);
string dir = HttpContext.Current.Request.QueryString["dir"];
string img = HttpContext.Current.Request.QueryString["img"];
bool force = HttpContext.Current.Request.QueryString["force"] == "yes";
double w = 0;
double h = 0;
string path = null;
Image orig = null;
Image thumb = null;
//make sure we have a directory and image filename
if (string.IsNullOrEmpty(dir))
return;
//make sure that we allow access to that directory, could do some extra sneaky security stuff here if we had to... (only accept a DirectoryID so the user doesn't know the actual path)
switch (dir)
{
case "user":
dir = "assets/images/users";
if (string.IsNullOrEmpty(img) || img == "undefined") img = "0.jpg";
break;
break;
case "icon":
dir = "assets/images/icons";
break;
default:
dir = "assets/images";
break;
}
//make sure that the image filename is just a filename
if (img.IndexOf("/") > -1 | img.IndexOf("\\") > -1)
return;
//make sure the image exists
path = HttpContext.Current.Server.MapPath("~/" + dir + "/" + img);
if (System.IO.File.Exists(path))
{
orig = Image.FromFile(path);
}
else
{
return;
}
//if there is a max width or height
if (double.TryParse(HttpContext.Current.Request.QueryString["w"], out w) | double.TryParse(HttpContext.Current.Request.QueryString["h"], out h))
{
//thumb is the resized image
double s = 1;
if (w > 0 & h > 0)
{
double ratio = h / w;
if (orig.Height / (double)orig.Width > ratio)
{
if (orig.Height > h)
{
if (force)
s = w / (double)orig.Width;
else
s = h / (double)orig.Height;
}
}
else
{
if (orig.Width > w)
{
if (force)
s = h / (double)orig.Height;
else
s = w / (double)orig.Width;
}
}
}
else if (w > 0)
{
if (orig.Width > w)
{
s = w / (double)orig.Width;
}
}
else if (h > 0)
{
if (orig.Height > h)
{
s = h / (double)orig.Height;
}
}
//double flip gets it to lose the embedded thumbnail
//https://web.archive.org/web/20200508200042/http://www.4guysfromrolla.com:80/articles/012203-1.2.aspx
orig.RotateFlip(RotateFlipType.Rotate180FlipNone);
orig.RotateFlip(RotateFlipType.Rotate180FlipNone);
thumb = orig.GetThumbnailImage(Convert.ToInt32(orig.Width * s), Convert.ToInt32(orig.Height * s), null, IntPtr.Zero);
if (force && w > 0 & h > 0)
thumb = cropImage(thumb, (int)w, (int)h);
}
else
{
//thumb is the image at it's original size
thumb = orig;
}
HttpContext.Current.Response.ContentType = "image/jpeg";
thumb.Save(HttpContext.Current.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
private Image cropImage(Image img, int w, int h)
{
if (w > img.Width && h > img.Height)
return img;
Rectangle cropArea = new Rectangle((img.Width - w) / 2, (img.Height - h) / 2, w, h);
Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
return (Image)(bmpCrop);
}
public bool IsReusable {
get {
return false;
}
}