17.1 图像操作

news2025/2/2 7:51:35

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

17.1.1 Image类

Image类为源自 Bitmap 和 Metafile 的类提供功能的抽象基类。

Image的属性大多数是只读的:

  1. FrameDimensionsList:获取GUID的数组,这些GUID表示Image中帧的维数。
  2. Size:获取此图像的宽度和高度(单位:像素)。
  3. Width:获取Image的宽度(单位:像素)。
  4. Height:获取Image的高度(单位:像素)。
  5. HorizontalResolution:获取水平分辨率(单位:像素/英寸)。
  6. VerticalResolution:获取垂直分辨率(单位:像素/英寸)。
  7. PixelFormat:获取Image中每个像素的颜色数据的格式。
  8. PropertyIdList:获取存储于Image中的属性项的ID。
  9. PropertyItems:获取存储于Image中的所有属性项(元数据片)。
  10. RawFormat:获取Image的文件格式。

Image常用方法:

  1. Clone:创建此 Image 的一个精确副本。
  1. FromFile:从指定的文件创建Image。
  2. FromHbitmap:从GDI位图的句柄创建Bitmap。
  3. FromStream:从指定的数据流创建Image。
  4. FrameDimensionsList:获取GUID数组,这些GUID表示此Image中帧的维数。
  5. GetBounds:以指定的单位获取图像的界限。
  6. GetEncoderParameterList:返回有关指定的图像编码器所支持的参数的信息。
  7. GetFrameCount:返回指定维度的帧数。
  8. GetPropertyItem:获取指定的属性项。
  9. GetThumbnailImage:返回缩略图。
  10. IsAlphaPixelFormat:获取像素格式是否包含alpha信息。
  11. RemovePropertyItem:从Image移除指定的属性项。
  12. RotateFlip:旋转、翻转或者同时旋转和翻转Image。
  13. Save:保存到指定的文件或流。
  14. SaveAdd:在上一Save方法调用所指定的文件或流内添加一帧。
  15. SelectActiveFrame:选择由维度和索引指定的帧。
  16. SetPropertyItem:存储一个属性项。

由于Image类没有提供构造函数,只能通过FromFile、FromStream或者FromHbitmap方法来创建Image对象实例。

【例 17.1【项目:code17-001】获取图片信息。

        private void button1_Click(object sender, EventArgs e)

        {

            string imgfile;

            OpenFileDialog ofd =new OpenFileDialog();

            ofd.Filter = "图片文件|*.jpg;*.bmp;*.png;*.gif";

            if (ofd.ShowDialog() != DialogResult.OK)

                return;

            imgfile = ofd.FileName;

            //从图片文件创建Image实例

            Image img  = Image.FromFile(imgfile);

            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

            pictureBox1.Image = img;

            textBox1.Text = "图片高度:" + img.Height + "\r\n";

            textBox1.Text += "图片宽度:" + img.Width + "\r\n";

            textBox1.Text += "图片水平分辨率:" + img.HorizontalResolution + "\r\n";

            textBox1.Text += "图片垂直分辨率:" + img.VerticalResolution + "\r\n";

            textBox1.Text += "文件格式:" + img.RawFormat.ToString() + "\r\n";

            textBox1.Text += "像素格式:" + img.PixelFormat.ToString() + "\r\n";

        }

运行结果如下图所示:

图17-1 获取图片信息

【例 17.2【项目:code17-002】翻转和旋转图片。

请在窗体上放置两个Button控件、一个ComboBox控件、一个PictureBox控件。

本例主要使用Image类的RotateFlip方法,它的参数是一个RotateFlipType枚举,包含以下成员:

  1. RotateNoneFlipNone:指定不进行旋转和翻转。
  2. RotateNoneFlipX:水平翻转。
  3. RotateNoneFlipY:垂直翻转。
  4. RotateNoneFlipXY:水平翻转和垂直翻转。
  5. Rotate90FlipNone: 90度顺时针旋转。
  6. Rotate90FlipX:水平翻转和90度顺时针旋转。
  7. Rotate90FlipY:垂直翻转和90度顺时针旋转。
  8. Rotate90FlipXY:水平翻转、垂直翻转和90度顺时针旋转。
  9. Rotate180FlipNone:180度顺时针旋转。
  10. Rotate180FlipX:水平翻转和180度顺时针旋转。
  11. Rotate180FlipY:垂直翻转和180度顺时针旋转。
  12. Rotate180FlipXY:水平翻转、垂直翻转和180度顺时针旋转。
  13. Rotate270FlipNone:270度顺时针旋转。
  14. Rotate270FlipX:水平翻转和270度顺时针旋转。
  15. Rotate270FlipY:垂直翻转和270度顺时针旋转。
  16. Rotate270FlipXY:水平翻转、垂直翻转和270度顺时针旋转。

请在ComboBox的Items属性中加入以上成员的名称。同时,为了观察图片变化,请将PictureBox控件的SizeMode 属性设置为AutoSize。具体代码如下:

        //窗体级变量,保存打开的图片

        Image sourceImg;

        //打开图片并显示在图片框内

        private void Button1_Click(object sender, EventArgs e)

        {

            string imgfile;

            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "图片文件|*.jpg";

            if (ofd.ShowDialog() != DialogResult.OK)

                return;

            imgfile = ofd.FileName;

            //从图片文件创建Image实例

            sourceImg = Image.FromFile(imgfile);

            pictureBox1.Image = sourceImg;

        }

        private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)

        {

            if (pictureBox1.Image == null)

                return;

            Image destImg;

            //克隆图片

            destImg = (Image)sourceImg.Clone();

            //根据组合框文本,使用RotateFlip方法旋转图片

            switch( comboBox1.Text)

            {

                case "Rotate180FlipX":

                    destImg.RotateFlip(RotateFlipType.Rotate180FlipX);

                    break;

                case "Rotate180FlipNone":

                    destImg.RotateFlip(RotateFlipType.Rotate180FlipNone);

                    break;

                case "Rotate180FlipXY":

                    destImg.RotateFlip(RotateFlipType.Rotate180FlipXY);

                    break;

                case "Rotate180FlipY":

                    destImg.RotateFlip(RotateFlipType.Rotate180FlipY);

                    break;

                case "Rotate270FlipNone":

                    destImg.RotateFlip(RotateFlipType.Rotate270FlipNone);

                    break;

                case "Rotate270FlipX":

                    destImg.RotateFlip(RotateFlipType.Rotate270FlipX);

                    break;

                case "Rotate270FlipXY":

                    destImg.RotateFlip(RotateFlipType.Rotate270FlipXY);

                    break;

                case "Rotate90FlipNone":

                    destImg.RotateFlip(RotateFlipType.Rotate90FlipNone);

                    break;

                case "Rotate90FlipX":

                    destImg.RotateFlip(RotateFlipType.Rotate90FlipX);

                    break;

                case "Rotate90FlipXY":

                    destImg.RotateFlip(RotateFlipType.Rotate90FlipXY);

                    break;

                case "Rotate90FlipY":

                    destImg.RotateFlip(RotateFlipType.Rotate90FlipY);

                    break;

                case "RotateNoneFlipNone":

                    destImg.RotateFlip(RotateFlipType.RotateNoneFlipNone);

                    break;

                case "RotateNoneFlipX":

                    destImg.RotateFlip(RotateFlipType.RotateNoneFlipX);

                    break;

                case "RotateNoneFlipXY":

                    destImg.RotateFlip(RotateFlipType.RotateNoneFlipXY);

                    break;

                case "RotateNoneFlipY":

                    destImg.RotateFlip(RotateFlipType.RotateNoneFlipY);

                    break;

            }

            pictureBox1.Image = destImg;

        }

        //保存旋转后的图片

        private void Button2_Click(object sender, EventArgs e)

        {

            string imgfile;

            SaveFileDialog sfd = new SaveFileDialog();

            sfd.Filter = "图片文件|*.jpg";

            if (sfd.ShowDialog() != DialogResult.OK)

                return;

            imgfile = sfd.FileName;

            //Save方法保存图片

            pictureBox1.Image.Save(imgfile, System.Drawing.Imaging.ImageFormat.Jpeg);

        }

    }

运行结果如下图所示:

图17-2 图片的翻转和旋转

17.1.2 Bitmap类

Bitmap类常用于封装 GDI+ 位图、处理由像素数据定义的图像的对象。

由于Bitmap类继承于Image类,Image类的属性和方法都可以使用。

Bitmap特有方法:

  1. FromHicon:从图标的Windows句柄创建 Bitmap。
  2. FromResource:从指定的Windows资源创建 Bitmap。
  3. GetPixel:获取Bitmap中指定坐标位置像素的颜色。
  4. SetPixel:设置Bitmap中指定坐标位置像素的颜色。
  5. LockBits:将Bitmap锁定到系统内存中。
  6. UnlockBits:从系统内存解锁Bitmap。
  7. MakeTransparent:用默认或指定的颜色使Bitmap透明。

创建一个Bitmap实例,常采用以下方法:

1、使用Bitmap的构造函数。

Bitmap提供了12种构造函数,常用的是:

  1. Bitmap(String):从指定的文件初始化Bitmap类的新实例。例如:

Bitmap sourceImg = new Bitmap("c:\\lessons\\3.jpg");

  1. Bitmap(Int32, Int32):用指定的宽度和高度初始化Bitmap类的新实例。例如:

Bitmap sourceImg = new Bitmap(this.Width ,this.Height);

2、使用方法创建:

  1. FromFile(String):使用Image的方法从指定的文件创建Bitmap。例如:

Bitmap sourceImg = (Bitmap)Image.FromFile("c:\\lessons\\3.jpg");

  1. Clone:创建此 Bitmap的一个精确副本

Bitmap destImg = (Bitmap)sourceImg.Clone();

Bitmap类的操作和Image类类似,这里不再累述。

17.1.3 获得图片Exif信息

有些照片保存了拍摄时使用的的相机品牌、型号以及GPS、光圈、快门、白平衡、ISO、焦距、日期时间等信息,通常称为Exif(Exchangeable image file format)信息,保存在Jpg文件头部。

使用Image类或Bitmap类的PropertyItems属性很容易获得图片的Exif信息。

PropertyItems是一个PropertyItem类数组,这些对象分别对应于此图像中存储的每个属性项。

注意:PropertyItem类位于System.Drawing.Imaging命名空间。

PropertyItem有4个属性:

  1. Id:某个图像信息的ID。
  2. Value:某个图像信息的值。
  3. Len:Value属性的长度(以字节为单位)。
  4. Type:整数,它定义了Value 属性包含的数据类型。

使用PropertyItem需要注意以下事项:

1、不同的Id有着不同的含义,例如Id从0至26都是关于gps信息。还有些常见信息如下(Id使用的是十六进制表示):

  1. 010F:PropertyTagEquipMake,相机生产厂家。
  2. 0110:PropertyTagEquipModel,相机型号。
  1. 829A:PropertyTagExifExposureTim,快门速度。
  2. 829D:PropertyTagExifFNumber,光圈。
  3. 9000:PropertyTagExifVer,Exif版本。
  4. 9207:PropertyTagExifMeteringMod,曝光的测光方法。
  5. 920A:PropertyTagExifFocalLength,焦距。

更多Id及其相关说明可以参看:Property item descriptions - Win32 apps | Microsoft Learn

2、不同的Type对应不同的数据类型,但是还是需要根据具体的Id来处理数据。表17-1列出了Type值对应的主要的数据类型:

表17-1 Type说明

表示的类型

1

字节数组。

2

ASCII字符串,末尾以字符0结束。使用此类型时,对应的Len属性应设置为包括字符0的字符串长度。例如,字符串“Hello”的长度为6。

3

无符号的短(16位)整型数组。

4

无符号的长(32位)整型数组。

5

无符号的长整型对数组。

6

可以包含任何数据类型的值的字节数组。

7

有符号的长(32位)整型数组。

10

有符号的长整型对数组。

从表17-1可以看出,类型5和10是长整型对数组,每个长整型对的长度为8字节,前面用来表示分数,前4个字节是分子,后4个字节是分母。可以使用BitConverter 类将基础数据类型与字节数组相互转换,具体代码请参看【例 17.3】。

分数值具体用带“/”的分数表示还是小数值表示,应该参考日常摄影术语。例如

829A(快门速度)获得的值为1/60,表示为1/60;

829D(光圈)获得的值为45/10,表示为4.5;

920A(焦距)获得的值为33/5,表示为6.6。

3、即使Type值相同,处理数据的方式也可能不同。

例如Id为9000和Id为9101这两个图像信息,Type都是7,但是处理方式不相同:

9000(PropertyTagExifVer),获得的字节数组为:48,50,50,48,对应ASCII字符为:0220,也就是图片数据Exif版本为0220。

9101(PropertyTagExifCompConfig),获得的字节数组为:1,2,3,0。对应的数据就是1230,像素数据的顺序. 大多数情况下RGB格式使用4,5,6,0,而YCbCr 格式使用1,2,3,0。

【例 17.3【项目:code17-003】获取图片的Exif信息。

        private void button1_Click(object sender, EventArgs e)

        {

            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "JPG文件|*.jpg";

            ofd.FileName = "";

            if (ofd.ShowDialog() != DialogResult.OK)

                return;

            string filename;

            filename = ofd.FileName;

            getPicInfo(filename);

        }

        //获得图片中的exif信息

        private void getPicInfo(string picFullPath)

        {

            listBox1.Items.Clear();

            Bitmap bmp =new Bitmap(picFullPath);

            string strPro = "";

            //不断枚举PropertyItems里面的内容

            foreach(System.Drawing.Imaging.PropertyItem pro in bmp.PropertyItems)

            {

                string strTmp;

                //根据类型进行大致处理,实际处理的时候应该根据具体的Id号进行处理

                switch( pro.Type)

                {

                        case 1:

                        strTmp = "length:" + pro.Len;

                        break;

                    case 2:

                        strTmp = System.Text.Encoding.ASCII.GetString(pro.Value).Replace("\0", "");

                        break;

                    case 3:

                        strTmp = BitConverter.ToInt16(pro.Value, 0).ToString();

                        break;

                    case 4:

                        strTmp = BitConverter.ToInt32(pro.Value, 0).ToString();

                        break;

                    case 5:

                        strTmp = getvalue(pro.Id, pro.Value).ToString();

                        break;

                    case 6:

                        strTmp = "type:" + pro.Type + " " + pro.Value.ToString();

                        break;

                    case 7:

                        strTmp = getascvalue(pro.Id, pro.Value);

                        break;

                    case 10:

                        strTmp = getvalue(pro.Id, pro.Value).ToString();

                        break;

                    default:

                    strTmp = "type:" + pro.Type + " " + pro.Value.ToString();

                        break;

                }

                //按照 Id-数据长度-数据类型-数据 显示

                listBox1.Items.Add(pro.Id.ToString("x").ToUpper() + "--" + pro.Len + "--" + pro.Type + "--" + strTmp);

            }

        }

       

        //处理整型对

        private string getvalue(int id, byte[] bteValue)

        {

            int intFirst;

            int intSecond;

            if (bteValue.Length == 8)

            {

                //将字节数组前4位转为Int32

                intFirst = BitConverter.ToInt32(bteValue, 0);

                //将字节数组后4为转为Int32

                intSecond = BitConverter.ToInt32(bteValue, 4);

                //如果是快门速度,那么返回分数,否则返回小数

                if (id == 33434)

                    return intFirst.ToString() + "/" + intSecond.ToString();

                return (intFirst / intSecond).ToString();

            }

            else

                //更多的数据不再处理

                return "0";

        }

        private string getascvalue(int id, byte[] bteValue)

        {

            if (bteValue.Length > 8)

                return ("length:" + bteValue.Length);

            if (id == 36864)

                return (Encoding.ASCII.GetString(bteValue));

            string returnString="";

            for (int i = 0;i< bteValue.Length; i++)

                returnString += bteValue[i].ToString() + " ";

            return returnString;

        }

运行结果如下图所示:

图17-3 图片的Exif信息

【例 17.4【项目:code17-004】获取图片的经纬度信息。

通常情况下,通过Gps信息的经纬度和海拔高度就可以对坐标位置定位。图片Exif信息中就包含相关的经纬度信息(根据具体拍照设备设置),对应的PropertyItem.Id是从0至26。比较关键的几个Id是:

  1. 1:纬度参照,指示纬度是北纬还是南纬。值为N表示北纬;值为S表示南纬。
  2. 2:纬度。
  3. 3:经度参照,指示经度是东经还是西经。值为E表示东经;值为W表示西经。
  4. 4:经度。
  5. 5:海拔参照。值为0,表示海平面上;值为1,表示海平面下。
  6. 6:海拔。

其中,纬度和经度的Type是5,长度为24的字节数组,其中前8个字节表示度,中间8个字节表示分,末尾8个字节表示秒。而每8个字节都是一个整数对。里面的前4字节表示分子,后4字节表示分母。

具体代码如下:

       private void button1_Click(object sender, EventArgs e)

        {

            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "JPG文件|*.jpg";

            ofd.FileName = "";

            if (ofd.ShowDialog() != DialogResult.OK)

                return;

            string filename;

            filename = ofd.FileName;

            getPicGpsInfo(filename);

        }

       

        //获得图片的Gps信息

        private void getPicGpsInfo(string picFullPath)

        {

            listBox1.Items.Clear();

            Bitmap bmp =new Bitmap(picFullPath);

            string strPro = "";

   

            //纬度参照

            string PropertyTagGpsLatitudeRef = "";

            //纬度

            string PropertyTagGpsLatitude = "";

            //经度参照

            string PropertyTagGpsLongitudeRef = "";

            //经度

            string PropertyTagGpsLongitude = "";

            //海拔参照

            string PropertyTagGpsAltitudeRef = "";

            //海拔

            string PropertyTagGpsAltitude = "";

   

            foreach(System.Drawing.Imaging.PropertyItem pro in bmp.PropertyItems)

            {

                switch(pro.Id)

                {

                    case 1:

                        PropertyTagGpsLatitudeRef = System.Text.Encoding.ASCII.GetString(pro.Value).Replace("\0", "");

                        break;

                    case 2:

                        PropertyTagGpsLatitude = getGpsLL(pro.Value);

                        break;

                    case 3:

                        PropertyTagGpsLongitudeRef = System.Text.Encoding.ASCII.GetString(pro.Value).Replace("\0", "");

                        break;

                    case 4:

                            PropertyTagGpsLongitude = getGpsLL(pro.Value);

                        break;

                    case 5:

                            PropertyTagGpsAltitudeRef = pro.Value[0].ToString();

                        break;

                    case 6:

                        PropertyTagGpsAltitude = getGpsAltitude(pro.Value);

                        break;

                    default:

                        //其它值不处理

                        break;

                }

            }

            if (PropertyTagGpsLatitude != "")

            {

                switch (PropertyTagGpsLatitudeRef)

                {

                    case "":

                    case "N":

                        listBox1.Items.Add("纬度:北纬 " + PropertyTagGpsLatitude);

                        break;

                    default:

                        listBox1.Items.Add("纬度:南纬 " + PropertyTagGpsLatitude);

                        break;

                }

            }

            else

                listBox1.Items.Add("纬度:没有纬度位置");

            if (PropertyTagGpsLongitude != "")

            {

                switch (PropertyTagGpsLongitudeRef)

                {

                    case "":

                    case "E":

                        listBox1.Items.Add("经度:东经 " + PropertyTagGpsLongitude);

                        break;

                    default:

                        listBox1.Items.Add("经度:西经 " + PropertyTagGpsLongitude);

                        break;

                }

            }

            else

                listBox1.Items.Add("经度:没有经度位置");

            if (PropertyTagGpsAltitude != "")

            {

                switch (PropertyTagGpsAltitudeRef)

                {

                    case "":

                    case "0":

                        listBox1.Items.Add("海拔:" + PropertyTagGpsAltitude);

                        break;

                    default:

                        listBox1.Items.Add("海拔:-" + PropertyTagGpsAltitude);

                        break;

                }

            }

            else

                listBox1.Items.Add("海拔:没有海拔高度");

         }

         //获取纬度和经度的度分秒

        private string getGpsLL(byte[] bteValue)

        {

            if (bteValue.Length != 24)

                return "";

            string strTmp = "";

            int intFirst;

            int intSecond;

            //前8个字节是度

            intFirst = BitConverter.ToInt32(bteValue, 0);

            intSecond = BitConverter.ToInt32(bteValue, 4);

            strTmp += (intFirst / intSecond).ToString() + "°";

            //中间8个字节是分

            intFirst = BitConverter.ToInt32(bteValue, 8);

            intSecond = BitConverter.ToInt32(bteValue, 12);

            strTmp += (intFirst / intSecond).ToString() + "'";

            //末尾8个字节是秒

            intFirst = BitConverter.ToInt32(bteValue, 16);

            intSecond = BitConverter.ToInt32(bteValue, 20);

            strTmp += (intFirst / intSecond).ToString() + "\"";

           return strTmp;

       }

        //获取海拔

        private string getGpsAltitude(byte[] bteValue)

        {

            if (bteValue.Length != 8)

                return "";

            int intFirst;

            int intSecond;

            intFirst = BitConverter.ToInt32(bteValue, 0);

            intSecond = BitConverter.ToInt32(bteValue, 4);

            return (intFirst / intSecond).ToString() + "米";

        }

运行结果如下图所示:

图17-4 图片的Gps信息

学习更多vb.net知识,请参看vb.net 教程 目录

学习更多C#知识,请参看C#教程 目录

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2289687.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件工程概论试题五

一、多选 1.好的软件的基本属性包括()。 A. 效率 B. 可依赖性和信息安全性 C. 可维护性 D.可接受性 正答&#xff1a;ABCD 2.软件工程的三要素是什么()? A. 结构化 B. 工具 C.面向对象 D.数据流! E.方法 F.过程 正答&#xff1a;BEF 3.下面中英文术语对照哪些是正确的、且是属…

深入解析“legit”的地道用法——从俚语到正式表达:Sam Altman用来形容DeepSeek: legit invigorating(真的令人振奋)

深入解析“legit”的地道用法——从俚语到正式表达 一、引言 在社交媒体、科技圈甚至日常对话中&#xff0c;我们经常会看到或听到“legit”这个词。比如最近 Sam Altman 在 X&#xff08;原 Twitter&#xff09;上发的一条帖子中写道&#xff1a; we will obviously deliver …

行业规范要当作业务实体画出来吗

第五元素 总觉得这些没有逻辑的实体&#xff0c;在绘制的时候不应该绘出来&#xff0c;他们没有责任啊。 比如以下:查阅规范 感觉不太对 UMLChina潘加宇 你这个规范是一个电脑系统还是一本书 第五元素 是书 UMLChina潘加宇 书没有智能&#xff0c;唯一暴露的接口是“翻”…

Cubemx文件系统挂载多设备

cubumx版本&#xff1a;6.13.0 芯片&#xff1a;STM32F407VET6 在上一篇文章中介绍了Cubemx的FATFS和SD卡的配置&#xff0c;由于SD卡使用的是SDIO通讯&#xff0c;因此具体驱动不需要自己实现&#xff0c;Cubemx中就可以直接配置然后生成SDIO的驱动&#xff0c;并将SD卡驱动和…

[Linux]从零开始的STM32MP157 U-Boot移植

一、前言 在上一次教程中&#xff0c;我们了解了STM32MP157的启动流程与安全启动机制。我们还将FSBL的相关代码移植成功了。大家还记得FSBL的下一个步骤是什么吗&#xff1f;没错&#xff0c;就是SSBL&#xff0c;而且常见的我们将SSBL作为存放U-Boot的地方。所以本次教程&…

前端 | 深入理解Promise

1. 引言 JavaScript 是一种单线程语言&#xff0c;这意味着它一次仅能执行一个任务。为了处理异步操作&#xff0c;JavaScript 提供了回调函数&#xff0c;但是随着项目处理并发任务的增加&#xff0c;回调地狱 (Callback Hell) 使异步代码很难维护。为此&#xff0c;ES6带来了…

【数据结构】_链表经典算法OJ:合并两个有序数组

目录 1. 题目描述及链接 2. 解题思路 3. 程序 3.1 第一版 3.2 第二版 1. 题目描述及链接 题目链接&#xff1a;21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。 新链表是通过拼接给…

C++ 字母大小写转换两种方法统计数字字符的个数

目录 题目&#xff1a; 代码1&#xff1a; 代码2&#xff1a; 题目&#xff1a; 大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。 输入格式 输入一行&#x…

终极版已激活!绿话纯净,打开即用!!!

今天我想和大家聊聊一个非常实用的工具——视频转换大师最终版。 视频转换大师终极版&#xff0c;堪称一款全能型的视频制作神器&#xff0c;集视频转换与编辑功能于一体。它搭载的视频增强器技术&#xff0c;能够最大限度地保留原始视频质量&#xff0c;甚至还能实现质量的进…

【2025年最新版】Java JDK安装、环境配置教程 (图文非常详细)

文章目录 【2025年最新版】Java JDK安装、环境配置教程 &#xff08;图文非常详细&#xff09;1. JDK介绍2. 下载 JDK3. 安装 JDK4. 配置环境变量5. 验证安装6. 创建并测试简单的 Java 程序6.1 创建 Java 程序&#xff1a;6.2 编译和运行程序&#xff1a;6.3 在显示或更改文件的…

C++ strcpy和strcat讲解

目录 一. strcpy 代码演示&#xff1a; 二.strcat 代码演示&#xff1a; 一. strcpy 使⽤字符数组可以存放字符串&#xff0c;但是字符数组能否直接赋值呢&#xff1f; ⽐如&#xff1a; char arr1[] "abcdef"; char arr2[20] {0}; arr2 arr1;//这样这节赋值可…

STM32 01 LED

一、点亮一个LED 在STC-ISP中单片机型号选择 STC89C52RC/LE52RC&#xff1b;如果没有找到hex文件&#xff08;在objects文件夹下&#xff09;&#xff0c;在keil中options for target-output- 勾选 create hex file。 如果要修改编程 &#xff1a;重新编译-下载/编程-单片机重…

【图床配置】PicGO+Gitee方案

【图床配置】PicGOGitee方案 文章目录 【图床配置】PicGOGitee方案为啥要用图床图床是什么配置步骤下载安装PicGoPicGo配置创建Gitee仓库Typora中的设置 为啥要用图床 在Markdown中&#xff0c;图片默认是以路径的形式存在的&#xff0c;类似这样 可以看到这是本地路径&#x…

AI软件外包需要注意什么 外包开发AI软件的关键因素是什么 如何选择AI外包开发语言

1. 定义目标与需求 首先&#xff0c;要明确你希望AI智能体做什么。是自动化任务、数据分析、自然语言处理&#xff0c;还是其他功能&#xff1f;明确目标可以帮助你选择合适的技术和方法。 2. 选择开发平台与工具 开发AI智能体的软件时&#xff0c;你需要选择适合的编程语言、…

ArkTS语言介绍

文章目录 一、基本知识声明类型运算符语句函数函数声明可选参数Rest参数返回类型函数的作用域函数调用函数类型箭头函数(又名Lambda函数)闭包函数重载类字段方法构造函数可见性修饰符对象字面量抽象类接口接口属性接口继承抽象类和接口泛型类型和函数泛型类和接口泛型约束泛型…

基于 oneM2M 标准的空气质量监测系统的互操作性

论文标题 英文标题&#xff1a; Interoperability of Air Quality Monitoring Systems through the oneM2M Standard 中文标题&#xff1a; 基于 oneM2M 标准的空气质量监测系统的互操作性 作者信息 Jonnar Danielle Diosana, Gabriel Angelo Limlingan, Danielle Bryan Sor…

Flutter常用Widget小部件

小部件Widget是一个类&#xff0c;按照继承方式&#xff0c;分为无状态的StatelessWidget和有状态的StatefulWidget。 这里先创建一个简单的无状态的Text小部件。 Text文本Widget 文件&#xff1a;lib/app/app.dart。 import package:flutter/material.dart;class App exte…

电路研究9.2.6——合宙Air780EP中HTTP——HTTP GET 相关命令使用方法研究

这个也是一种协议类型&#xff1a; 14.16 使用方法举例 根据之前多种类似的协议的相关信息&#xff1a; HTTP/HTTPS&#xff1a;超文本传输协议&#xff08;HTTP&#xff09;用于Web数据的传输&#xff0c;而HTTPS是HTTP的安全版本&#xff0c;使用SSL/TLS进行加密。与FTP相比&…

【力扣】283.移动零

AC截图 题目 思路 遍历nums数组&#xff0c;将0删除并计数&#xff0c;最后在nums数组尾部添加足量的零 有一个问题是&#xff0c;vector数组一旦erase某个元素&#xff0c;会导致迭代器失效。好在有解决办法&#xff0c;erase会返回下一个有效元素的新迭代器。 代码 class …

linux设置mysql远程连接

首先保证服务器开放了mysql的端口 然后输入 mysql -u root -p 输入密码后即可进入mysql 然后再 use mysql; select user,host from user; update user set host"%" where user"root"; flush privileges; 再执行 select user,host from user; 即可看到变…