【问题标题】:C# combine two images code is ugly...how to make it better? [closed]C#结合两个图像代码很丑...如何使它更好? [关闭]
【发布时间】:2014-02-15 12:33:40
【问题描述】:

我的任务是将两个图像发布到服务器,将它们组合(一个在另一个之上),然后将生成的图像保存到 Azure 存储。我有有效的代码,但它看起来......错误。 有没有更丑陋的方法来做到这一点?我讨厌看到所有那些“使用”语句和长缩进。

此代码将签名图像和姓名缩写图像组合在一起,然后将结果保存到 Azure 存储。

代码:

        string initialscontainerPath = "signatures/initailsdata.png";

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(Microsoft.WindowsAzure.CloudConfigurationManager.GetSetting("StorageConnection"));
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference(Request.Url.Host.ToLower().Replace(".", "-"));
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(initialscontainerPath);
        blockBlob.Properties.ContentType = "image/png";

        byte[] initialsbytes = Convert.FromBase64String(initialsData);

        byte[] signaturebytes = Convert.FromBase64String(signatureData);


        using (System.IO.MemoryStream msinitials = new System.IO.MemoryStream(initialsbytes))
        {
            using (System.IO.MemoryStream mssignature = new System.IO.MemoryStream(signaturebytes))
            {
                using (System.Drawing.Image bminitials = new System.Drawing.Bitmap(msinitials))
                {
                    using (System.Drawing.Image bmsignature = new System.Drawing.Bitmap(mssignature))
                    {
                        using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmsignature))
                        {
                            g.DrawImage(bminitials, 0, 0);

                            using (System.IO.MemoryStream savestream = new System.IO.MemoryStream())
                            {
                                bmsignature.Save(savestream, System.Drawing.Imaging.ImageFormat.Png);

                                using (System.IO.MemoryStream uploadstream = new System.IO.MemoryStream(savestream.ToArray()))
                                {
                                    blockBlob.UploadFromStream(uploadstream);
                                }
                            }
                        }
                    }
                }
            }
        }

【问题讨论】:

  • 这个问题属于codereview.stackexchange.com

标签: c# image memorystream


【解决方案1】:

您是否考虑过在另一个之上绘制一个?只需将图像读入位图对象,然后在另一个之上绘制较小的图像,有点像这样:

public Bitmap Combine(Bitmap largeBmp, Bitmap smallBmp) {
    Graphics g = Graphics.FromImage(largeBmp);
    g.CompositingMode = CompositingMode.SourceOver;
    int margin = 5;
    int x = largeBmp.Width - smallBmp.Width - margin;
    int y = largeBmp.Height - smallBmp.Height - margin;
    g.DrawImage(smallBmp, new Point(x, y));
    return largeBmp;
}

请注意,x 和 y 是小图像要退出大图像的坐标。

希望对你有帮助

【讨论】:

    【解决方案2】:

    Using just 被转换成 try...catch...finaly 块,并在 finaly 中释放变量。您还可以消除命名空间并在代码开头放置更多 using 语句。我认为这更具可读性:

    string initialscontainerPath = "signatures/initailsdata.png";
    
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(Microsoft.WindowsAzure.CloudConfigurationManager.GetSetting("StorageConnection"));
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference(Request.Url.Host.ToLower().Replace(".", "-"));
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(initialscontainerPath);
    blockBlob.Properties.ContentType = "image/png";
    
    byte[] initialsbytes = Convert.FromBase64String(initialsData);
    
    byte[] signaturebytes = Convert.FromBase64String(signatureData);
    
    CombineBitmaps(initialsbytes, signaturebytes);
    

    CombineBitmaps 在哪里

    private void CombineBitmaps(byte[] initialsbytes, byte[] signaturebytes, CloudBlockBlob blockBlob)
    {
        MemoryStream msinitials   = null;
        MemoryStream mssignature  = null;
        MemoryStream savestream   = null;
        MemoryStream uploadstream = null;
        Bitmap bminitials         = null;
        Bitmap bmsignature        = null;
        Graphics g                = null;
    
        try
        {
            msinitials  = new MemoryStream(initialsbytes);
            mssignature = new MemoryStream(signaturebytes);
            bminitials  = new Bitmap(msinitials);
            bmsignature = new Bitmap(mssignature);
            savestream  = new MemoryStream();
    
            g = Graphics.FromImage(bmsignature);
    
            g.DrawImage(bminitials, 0, 0);
    
            bmsignature.Save(savestream, ImageFormat.Png);
    
            uploadstream = new MemoryStream(savestream.ToArray());
    
            blockBlob.UploadFromStream(uploadstream);
        }
        finally
        {
            DisposeNotNull(msinitials,  mssignature, bminitials, bmsignature, g, savestream, uploadstream);
        }
    }
    
    private void DisposeNotNull(params IDisposable[] objects)
    {
        foreach(IDisposable obj in objects)
            if (obj != null) obj.Dispose();
    }
    

    并且变量名可以使用一些帕斯卡大小写(或任何名称)。

    【讨论】:

    • 我喜欢这个。我认为在这种情况下,try catch 更容易阅读。我将把这个答案和 Hans Passant 的答案放到我的 IDE 中,看看我更喜欢哪个。
    猜你喜欢
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 2022-01-22
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多