【解決方法】このコードを使用して変換した 8000 以上の画像でメモリ不足エラーが発生した場合、C# の専門家がいる場合は元に戻してください。


C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Configuration;
using System.Data.SqlClient;
using iTextSharp.text.pdf.parser;
using Dotnet = System.Drawing.Image;
using iTextSharp.text.pdf;
using System.Drawing.Imaging;

namespace ImageConverter
{
    public partial class Form1 : Form
    {
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connect"].ConnectionString);
        SqlCommand cmd;
        DataTable dt;
        SqlDataAdapter sda;
        public Form1()
        {
            InitializeComponent();
        }

        private void Select_Path_Click(object sender, EventArgs e)
        {
            try
            {
                string newfile = "";
                string imgnewfile = "";
                string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath);
                if (Directory.Exists(Application.StartupPath + "/CanFiles") != true)
                {
                    Directory.CreateDirectory(Application.StartupPath + "/CanFiles");
                }

                foreach (string file in files)
                {
                    string fn = System.IO.Path.GetFileNameWithoutExtension(file);
                    if (System.IO.Path.GetExtension(file) == ".png" || System.IO.Path.GetExtension(file) == ".tiff" ||
                        System.IO.Path.GetExtension(file) == ".jpg" || System.IO.Path.GetExtension(file) == ".tif" ||
                        System.IO.Path.GetExtension(file) == ".gif" || System.IO.Path.GetExtension(file) == ".jfif" ||
                        System.IO.Path.GetExtension(file) == ".jpe" || System.IO.Path.GetExtension(file) == ".dib" ||
                        System.IO.Path.GetExtension(file) == ".bmp" || System.IO.Path.GetExtension(file) == ".JPG" ||
                        System.IO.Path.GetExtension(file) == ".BMP" || System.IO.Path.GetExtension(file) == ".JPE" || 
                        System.IO.Path.GetExtension(file) == ".GIF" || System.IO.Path.GetExtension(file) == ".PNG" ||
                        System.IO.Path.GetExtension(file) == ".jpeg" || System.IO.Path.GetExtension(file) == ".JPEG"
                            )
                    {

                        string fileName = System.IO.Path.GetFileNameWithoutExtension(file);
                        string filepath = System.IO.Path.GetFullPath(file);
                        string fileext = System.IO.Path.GetExtension(file);
                        try
                        {
                            using (Image newImage = Image.FromFile(filepath))
                            {
                                Bitmap image1 = new Bitmap(Image.FromFile(filepath));
                                newfile = Application.StartupPath + "/CanFiles/" + fileName + ".jpg";
                                string tempfileName = "";
                                if (System.IO.File.Exists(newfile))
                                {
                                    int counter = 2;
                                    while (System.IO.File.Exists(newfile))
                                    {
                                        tempfileName = Application.StartupPath + "/CanFiles/" + counter.ToString() + fileName + ".jpg";
                                        newfile = tempfileName;
                                        counter++;
                                    }

                                }

                                image1.Save(newfile, System.Drawing.Imaging.ImageFormat.Jpeg);
                                image1.Dispose();
                            }

                            GC.Collect();
                        }

                        catch (Exception)
                        {

                            listBox1.Items.Add("Corrupt FileName:" + fileName);
                            continue;
                        }


                    }

                    else
                    {
                        int pageNum = 1;
                        newfile = Application.StartupPath + "/CanFiles/";
                        PdfReader pdf = new PdfReader(file);
                        PdfDictionary pg = pdf.GetPageN(pageNum);
                        PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES));
                        PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));
                        if (xobj == null) { return; }
                        foreach (PdfName name in xobj.Keys)
                        {
                            PdfObject obj = xobj.Get(name);
                            if (!obj.IsIndirect()) { continue; }
                            PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
                            PdfName type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));
                            if (!type.Equals(PdfName.IMAGE)) { continue; }
                            int XrefIndex = Convert.ToInt32(((PRIndirectReference)obj).Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
                            PdfObject pdfObj = pdf.GetPdfObject(XrefIndex);
                            PdfStream pdfStrem = (PdfStream)pdfObj;
                            byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)pdfStrem);
                            if (bytes == null) { continue; }
                            using (System.IO.MemoryStream memStream = new System.IO.MemoryStream(bytes))
                            {
                                memStream.Position = 0;
                                System.Drawing.Image img = System.Drawing.Image.FromStream(memStream);
                                if (!Directory.Exists(newfile))
                                    Directory.CreateDirectory(newfile);

                                string path = System.IO.Path.Combine(newfile, String.Format(@"{0}.jpg", fn));
                                System.Drawing.Imaging.EncoderParameters parms = new System.Drawing.Imaging.EncoderParameters(1);
                                parms.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 0);
                                var jpegEncoder = ImageCodecInfo.GetImageEncoders().ToList().Find(x => x.FormatID == ImageFormat.Jpeg.Guid);
                                img.Save(path, jpegEncoder, parms);
                            }
                            // <-- For debugging use.
                        }

                        //listBox1.Items.Add("Image Not Converted:"+fn);
                    }
                }
                GC.Collect();
                MessageBox.Show("Image Successfully Converted!");

                string[] imgfiles = Directory.GetFiles(Application.StartupPath + "/CanFiles/");
                foreach (string imgfile in imgfiles)
                {
                    if (imgfile.Contains("_Sign"))
                    {
                        string fileName = System.IO.Path.GetFileNameWithoutExtension(imgfile);
                        string filepath = System.IO.Path.GetFullPath(imgfile);
                        int lngimg = fileName.Length;
                        string imgname = fileName.Remove(lngimg - 5, 5);
                        //MessageBox.Show(""+imgname);
                        con.Open();

                        cmd = new SqlCommand("Get_MicaId_By_CandIdwise", con);
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@CanId", imgname);
                        sda = new SqlDataAdapter(cmd);
                        dt = new DataTable();
                        sda.Fill(dt);
                        foreach (DataRow row in dt.Rows)
                        {
                            string rollname = row["RollNo"].ToString();
                            imgnewfile = Application.StartupPath + "\\CanFiles\\" + rollname + "_Sign" + ".jpg";
                            File.Move(imgfile, imgnewfile);


                        }
                        con.Close();
                    }

                    else
                    {
                        string fileName = System.IO.Path.GetFileNameWithoutExtension(imgfile);
                        string filepath = System.IO.Path.GetFullPath(imgfile);
                        con.Open();

                        cmd = new SqlCommand("Get_MicaId_By_CandIdwise", con);
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@CanId", fileName);
                        sda = new SqlDataAdapter(cmd);
                        dt = new DataTable();
                        sda.Fill(dt);
                        foreach (DataRow row in dt.Rows)
                        {
                            string rollname = row["RollNo"].ToString();
                            imgnewfile = Application.StartupPath + "\\CanFiles\\" + rollname + ".jpg";
                            File.Move(imgfile, imgnewfile);
                        }
                        con.Close();
                    }

                }
                MessageBox.Show("Image Successfully Rename");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DialogResult result = folderBrowserDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath);
                lbl1.Text = "Images: " + files.Length.ToString();
            }
        }
    }
}

解決策 1

コード内で奇妙なことが起こっています。
たとえば次の行があります:

C#
picturebox1.Image = new Bitmap(Image.FromFile(filepath));
Bitmap image1 = new Bitmap(picturebox1.Image);
image1.Save(Application.StartupPath  + "/CanFiles/" + fileName + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

あるべきです

C#
Bitmap image1 = new Bitmap(Image.FromFile(filepath));
Bitmap image1 = Image.FromFile(filepath);
image1.Save(Path.Combine(Application.StartupPath, "CanFiles", fileName, ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
image1.Dispose();  // You need to free the memory of the image

PictureBox をループ内で使用する理由はありません。 画像がちらつくだけです。

また、次のようにすると読みやすく、より効率的になります。

C#
string extension = Path.GetExtension(file).ToUpper();
if (extension == ".PNG" || extension == ".TIFF" ||
    extension == ".JPG" || extension == ".TIF" ||
    extension == ".GIF" || extension == ".JFIF" ||
    extension == ".JPE" || extension == ".DIB" ||
    extension == ".BMP" || extension == ".JPEG")

[UPDATE]

この行を変更します

C#
Bitmap image1 = new Bitmap(Image.FromFile(filepath));

C#
Bitmap image1 = (Bitmap)Image.FromFile(filepath);

それ以外の場合は、2 つのイメージを作成し、1 つだけをリリースします。
(私は最初、この小さな「特別な」構造を見逃していました)
(ビットマップのタイプキャストを追加)

[UPDATE2]

コードは次のようになっているはずです。 そうですか?

C#
private void Select_Path_Click(object sender, EventArgs e)
{
    string directoryPath = Path.Combine(Application.StartupPath, "CanFiles");
    if (!Directory.Exists(directoryPath))
        Directory.CreateDirectory(directoryPath);
    
    foreach (string file in Directory.GetFiles(folderBrowserDialog1.SelectedPath))
    {
        string extension = Path.GetExtension(file).ToUpper();
        if (extension == ".PNG" || extension == ".TIFF" ||
            extension == ".JPG" || extension == ".TIF" ||
            extension == ".GIF" || extension == ".JFIF" ||
            extension == ".JPE" || extension == ".DIB" ||
            extension == ".BMP" || extension == ".JPEG")            
        {

            string filepath = Path.GetFullPath(file);
            Image image1 = Image.FromFile(filepath);

            string fileName = Path.ChangeExtension(file, ".jpg");

            string fileName = Path.ChangeExtension(Path.GetFileName(file), ".jpg");
            image1.Save(Path.Combine(directoryPath, fileName), System.Drawing.Imaging.ImageFormat.Jpeg);

            image1.Dispose();
        }
    }
    MessageBox.Show("Image Successfully Converted!");
}

[UPDATE3]

このコードをテストしたところ、それぞれ約 5 ~ 8 MB の 2000 個のイメージをあるディレクトリから別のディレクトリに問題なくコピーできました。
メモリ消費量は安定しています。

.jpg や .jpeg も「変換」する必要があるのか​​、それともこのタイプのファイルの場合は単にファイルをコピーするコードを追加する必要があるのか​​、再考した方がよいかもしれません。
使用する CPU が少なくなり、高速になります。
何かのようなもの:

C#
else if (extension == ".JPG" || extension == ".JPEG")
{
    File.Copy(oldPath, newPath);
}

コメント

タイトルとURLをコピーしました