图片合成YFFotoMix

简介: 图片合成YFFotoMix
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using YFAPICommon.Controllers;
namespace YFAPICommon.Libs
{
    public class YFFotoMix
    {
        private static string serverPath = System.Configuration.ConfigurationSettings.AppSettings["serverPath"];
        private static string localPath = System.Configuration.ConfigurationSettings.AppSettings["localPath"];
        /// <summary>
        /// 合成用户分享图片
        /// </summary>
        /// <returns></returns>
        public static string CombinUserShareImg(string str,string imgUrl,string wxPath,string fileName)
        {
            const string folderPath = "\\shareimg\\";
            const string serverFolderPath = "/shareimg/";
            string folder = localPath + folderPath;
            //判断文件的存在
            if (System.IO.File.Exists(Path.Combine(folder, fileName+".jpg")))
            {
                //存在文件
                return serverPath + serverFolderPath + fileName + ".jpg";
            }
            Image img1 = Image.FromFile(Path.Combine(folder, "sharetemp1.jpg"));//相框图片 
            Image img2 = DrawTransparentRoundCornerImage(downloadImage(imgUrl),30); //照片图片 
            Image wxQrCode = DrawTransparentRoundCornerImage(WXController.getWXCodeImage(wxPath));
            //从指定的System.Drawing.Image创建新的System.Drawing.Graphics       
            Graphics g = Graphics.FromImage(img1);
            g.DrawImage(img1, 0, 0, img1.Size.Width, img1.Size.Height);// g.DrawImage(imgBack, 0, 0, 相框宽, 相框高);
                                                                       //g.FillRectangle(System.Drawing.Brushes.Black, 16, 16, (int)112 + 2, ((int)73 + 2));//相片四周刷一层黑色边框
                                                                       //g.DrawImage(img, 照片与相框的左边距, 照片与相框的上边距, 照片宽, 照片高);
            g.DrawImage(img2, 75, 243, 650, 838);//户型图
            g.DrawImage(wxQrCode, 540, 1175, 200, 200);//小程序二维码
            //************************************
            g.TextRenderingHint = TextRenderingHint.AntiAlias;
            FontFamily fontFamily = new FontFamily("黑体");
            Font font1 = new Font(fontFamily, 28f, FontStyle.Regular, GraphicsUnit.Pixel);
            string poem1 = str;
            g.DrawString(poem1, font1, Brushes.White, 70, 1320);
            //************************************
            GC.Collect();
            img1.Save(Path.Combine(folder, fileName + ".jpg"));
            img1.Dispose();
            return serverPath+ serverFolderPath+ fileName + ".jpg";
        }
        public static string CombinUserShareImg2(string wxPath, string fileName)
        {
            const string folderPath = "\\shareimg\\";
            const string serverFolderPath = "/shareimg/";
            string folder = localPath + folderPath;
            //判断文件的存在
            if (System.IO.File.Exists(Path.Combine(folder, fileName + ".jpg")))
            {
                //存在文件
                return serverPath + serverFolderPath + fileName + ".jpg";
            }
            Image img1 = Image.FromFile(Path.Combine(folder, "sharetemp2.jpg"));//相框图片 
            Image wxQrCode = DrawTransparentRoundCornerImage(WXController.getWXCodeImage(wxPath));
            //从指定的System.Drawing.Image创建新的System.Drawing.Graphics       
            Graphics g = Graphics.FromImage(img1);
            g.DrawImage(img1, 0, 0, img1.Size.Width, img1.Size.Height);// g.DrawImage(imgBack, 0, 0, 相框宽, 相框高);
                                                                       //g.FillRectangle(System.Drawing.Brushes.Black, 16, 16, (int)112 + 2, ((int)73 + 2));//相片四周刷一层黑色边框
                                                                       //g.DrawImage(img, 照片与相框的左边距, 照片与相框的上边距, 照片宽, 照片高);
            g.DrawImage(wxQrCode, 590, 1225, 160, 160);//小程序二维码
            //************************************
            GC.Collect();
            img1.Save(Path.Combine(folder, fileName + ".jpg"));
            img1.Dispose();
            return serverPath + serverFolderPath + fileName + ".jpg";
        }
        //图片处理为圆角
        private static System.Drawing.Image DrawTransparentRoundCornerImage(System.Drawing.Image image,int radius)
        {
            Bitmap bm = new Bitmap(image.Width, image.Height);
            Graphics g = Graphics.FromImage(bm);
            g.FillRectangle(Brushes.Transparent, new Rectangle(0, 0, image.Width, image.Height));
            using (System.Drawing.Drawing2D.GraphicsPath path = CreateRoundedRectanglePath(new Rectangle(0, 0, image.Width, image.Height), radius))
            {
                g.SetClip(path);
            }
            g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
            g.Dispose();
            return bm;
        }
        //图片处理为圆形
        private static System.Drawing.Image DrawTransparentRoundCornerImage(System.Drawing.Image image)
        {
            Bitmap bm = new Bitmap(image.Width, image.Height);
            Graphics g = Graphics.FromImage(bm);
            g.FillRectangle(Brushes.Transparent, new Rectangle(0, 0, image.Width, image.Height));
            using (System.Drawing.Drawing2D.GraphicsPath path = CreateRoundedRectanglePath(new Rectangle(0, 0, image.Width, image.Height), image.Width / 2))
            {
                g.SetClip(path);
            }
            g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
            g.Dispose();
            return bm;
        }
        //设置图片四个边角弧度
        private static System.Drawing.Drawing2D.GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int cornerRadius)
        {
            System.Drawing.Drawing2D.GraphicsPath roundedRect = new System.Drawing.Drawing2D.GraphicsPath();
            roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
            roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
            roundedRect.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
            roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom);
            roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
            roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);
            roundedRect.CloseFigure();
            return roundedRect;
        }
        private static Image downloadImage(string url)
        {
            WebRequest imgRequest = WebRequest.Create(url);
            HttpWebResponse res;
            try
            {
                res = (HttpWebResponse)imgRequest.GetResponse();
            }
            catch (WebException ex)
            {
                res = (HttpWebResponse)ex.Response;
            }
            if (res.StatusCode.ToString() == "OK")
            {
                System.Drawing.Image downImage = System.Drawing.Image.FromStream(imgRequest.GetResponse().GetResponseStream());
                return downImage;
            }
            return null;
        }
    }
}
相关文章
|
消息中间件 缓存 算法
Java多线程面试题总结(上)
进程和线程是操作系统管理程序执行的基本单位,二者有明显区别: 1. **定义与基本单位**:进程是资源分配的基本单位,拥有独立的内存空间;线程是调度和执行的基本单位,共享所属进程的资源。 2. **独立性与资源共享**:进程间相互独立,通信需显式机制;线程共享进程资源,通信更直接快捷。 3. **管理与调度**:进程管理复杂,线程管理更灵活。 4. **并发与并行**:进程并发执行,提高资源利用率;线程不仅并发还能并行执行,提升执行效率。 5. **健壮性**:进程更健壮,一个进程崩溃不影响其他进程;线程崩溃可能导致整个进程崩溃。
106 2
开心档-软件开发入门之Python File(文件) 方法
本文主要讲解Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
开心档-软件开发入门之Python File(文件) 方法
|
14天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
9天前
|
缓存 并行计算 PyTorch
144_推理时延优化:Profiling与瓶颈分析 - 使用PyTorch Profiler诊断推理延迟,优化矩阵运算的独特瓶颈
在2025年的大模型时代,推理时延优化已经成为部署LLM服务的关键挑战之一。随着模型规模的不断扩大(从数亿参数到数千亿甚至万亿参数),即使在最先进的硬件上,推理延迟也常常成为用户体验和系统吞吐量的主要瓶颈。
341 147
|
9天前
|
机器学习/深度学习 存储 缓存
92_自我反思提示:输出迭代优化
在大型语言模型(LLM)应用日益普及的今天,如何持续提升模型输出质量成为了业界关注的核心问题。传统的提示工程方法往往依赖一次性输入输出,难以应对复杂任务中的多轮优化需求。2025年,自我反思提示技术(Self-Reflection Prompting)作为提示工程的前沿方向,正在改变我们与LLM交互的方式。这项技术通过模拟人类的自我反思认知过程,让模型能够对自身输出进行评估、反馈和优化,从而实现输出质量的持续提升。
392 136
|
3天前
|
人工智能 移动开发 自然语言处理
阿里云百炼产品月刊【2025年9月】
本月通义千问模型大升级,新增多模态、语音、视频生成等高性能模型,支持图文理解、端到端视频生成。官网改版上线全新体验中心,推出高代码应用与智能体多模态知识融合,RAG能力增强,助力企业高效部署AI应用。
223 1
|
13天前
|
存储 人工智能 搜索推荐
终身学习型智能体
当前人工智能前沿研究的一个重要方向:构建能够自主学习、调用工具、积累经验的小型智能体(Agent)。 我们可以称这种系统为“终身学习型智能体”或“自适应认知代理”。它的设计理念就是: 不靠庞大的内置知识取胜,而是依靠高效的推理能力 + 动态获取知识的能力 + 经验积累机制。
399 135