相同的图像调整大小和图像裁剪功能在Winforms应用程序中有效,并且在同一解决方案的

时间:2017-09-09 11:19:41

标签: c# winforms asp.net-web-api

简介: 我有这个解决方案,包括一个Webapi应用程序,Winforms(UI)应用程序,然后是Xamarin Forms(Android,UWP,iOS)。

现在,调整大小和裁剪功能在Winforms的应用程序中有效。由于我在我的Webapi应用PerformInitSetup()中使用初始化数据,我还想在此处应用缩略图生成功能。

这些是方法(放在每个应用程序的帮助器类中):

    public static Image CropImage(Image img, Rectangle cropArea)
    {
        Bitmap bmpImage = new Bitmap(img);
        Bitmap bmpCrop = bmpImage.Clone(cropArea,
        bmpImage.PixelFormat);
        return (Image)(bmpCrop);
    }

    public static Image ResizeImage(Image imgToResize, Size size)
    {
        int sourceWidth = imgToResize.Width;
        int sourceHeight = imgToResize.Height;

        float nPercent = 0;
        float nPercentW = 0;
        float nPercentH = 0;

        nPercentW = ((float)size.Width / (float)sourceWidth);
        nPercentH = ((float)size.Height / (float)sourceHeight);

        if (nPercentH < nPercentW)
            nPercent = nPercentH;
        else
            nPercent = nPercentW;

        int destWidth = (int)(sourceWidth * nPercent);
        int destHeight = (int)(sourceHeight * nPercent);

        Bitmap b = new Bitmap(destWidth, destHeight);
        Graphics g = Graphics.FromImage((Image)b);
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
        g.Dispose();

        return (Image)b;
    }

在Winforms应用程序(确实有效)中,这里是如何保存常规图像,然后是基于它生成的缩略图:

    private void btnAddImage_Click(object sender, EventArgs e)
    {
        if (openFileDialog.ShowDialog() == DialogResult.OK)
        {
            txtImage.Text = openFileDialog.FileName;
            Image originalImage = Image.FromFile(openFileDialog.FileName);

            MemoryStream ms = new MemoryStream();
            originalImage.Save(ms, ImageFormat.Jpeg);

            lodging.Image = ms.ToArray();


            int resizedImageWidth = Convert.ToInt32(ConfigurationManager.AppSettings["resizedImageWidth"]);
            int resizedImageHeight = Convert.ToInt32(ConfigurationManager.AppSettings["resizedImageHeight"]);
            int croppedImageWidth = Convert.ToInt32(ConfigurationManager.AppSettings["croppedImageWidth"]);
            int croppedImageHeight = Convert.ToInt32(ConfigurationManager.AppSettings["croppedImageHeight"]);

            if(originalImage.Width > resizedImageWidth)
            {
                Image resizedImage = Util.UIHelper.ResizeImage(originalImage, new Size(resizedImageWidth, resizedImageHeight));
                Image croppedImage = resizedImage;

                if(resizedImage.Width >= croppedImageWidth && resizedImage.Height >= croppedImageHeight)
                {
                    int croppedXPos = (resizedImageWidth - croppedImageWidth) / 2;
                    int croppedYPos = (resizedImageHeight - croppedImageHeight) / 2;

                    croppedImage = Util.UIHelper.CropImage(resizedImage, new Rectangle(croppedXPos, croppedYPos, croppedImageWidth, croppedImageHeight));

                    ms = new MemoryStream();
                    croppedImage.Save(ms, ImageFormat.Jpeg);
                    lodging.ImageThumb = ms.ToArray();

                }
            }
        }
    }

到目前为止,非常好。

但是当我尝试在Webapi应用程序的PerformInitSetup()方法中执行相同操作时,我收到错误(在底部找到它):

// ... other init data

MemoryStream ms1 = new MemoryStream();
Image img1 = Image.FromFile("D:\\Path\\To\\MyImage\\image.jpg");
img1.Save(ms1, ImageFormat.Jpeg);

MemoryStream img1Thumb = GenerateThumbnailImage(img1);

_ctx.LodgingDbSet.Add(new Lodging { Name = "Name Name", ... other attributes ... , Image = ms1.ToArray(), ImageThumb = img1Thumb.ToArray(), CityId = 1, UserId = 2 });

// ... other init data

InitDB : DropCreateDatabaseIfModelChanges<MyDbContext>方法的PerformInitSetup()类中,我有:

    private MemoryStream GenerateThumbnailImage(Image originalImage)
    {
        int resizedImageWidth = Convert.ToInt32(ConfigurationManager.AppSettings["resizedImageWidth"]);
        int resizedImageHeight = Convert.ToInt32(ConfigurationManager.AppSettings["resizedImageHeight"]);
        int croppedImageWidth = Convert.ToInt32(ConfigurationManager.AppSettings["croppedImageWidth"]);
        int croppedImageHeight = Convert.ToInt32(ConfigurationManager.AppSettings["croppedImageHeight"]);

        MemoryStream ms = new MemoryStream();

        if (originalImage.Width > resizedImageWidth)
        {
            Image resizedImage = Util.Helper.ResizeImage(originalImage, new Size(resizedImageWidth, resizedImageHeight));
            Image croppedImage = resizedImage;

            if (resizedImage.Width >= croppedImageWidth && resizedImage.Height >= croppedImageHeight)
            {
                int croppedXPos = (resizedImageWidth - croppedImageWidth) / 2;
                int croppedYPos = (resizedImageHeight - croppedImageHeight) / 2;

                croppedImage = Util.Helper.CropImage(
                    resizedImage,
                    new Rectangle(croppedXPos, croppedYPos, croppedImageWidth, croppedImageHeight)
                    );

                croppedImage.Save(ms, ImageFormat.Jpeg);
            }
        }

        return ms;
    }

我认为这会奏效。然而,有些事情是错误的,但不幸的是,由于某种原因,断点似乎不能在这个MyDbContext文件中工作(对其解释会很感激!),所以我收到了这个错误:

{"Message":
"An error has occurred.",
"ExceptionMessage":
    "Parameter is not valid.",
"ExceptionType":"System.ArgumentException",

"StackTrace":
"   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)\r\n
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)\r\n
at My_API.Util.Helper.ResizeImage(Image imgToResize, Size size) in D:\\Path\\To\\MyApp\\My_API\\Util\\Helper.cs:line 42\r\n
at My_API.DAL.InitDb.GenerateThumbnailImage(Image originalImage) in D:\\Path\\To\\MyApp\\My_API\\DAL\\MyDbContext.cs:line 341\r\n
at My_API.DAL.InitDb.PerformInitSetup(MyDbContext _ctx) in D:\\Path\\To\\MyApp\\My_API\\DAL\\MyDbContext.cs:line 176\r\n
at My_API.DAL.InitDb.Seed(MyDbContext _ctx) in D:\\Path\\To\\MyApp\\My_API\\DAL\\MyDbContext.cs:line 67\r\n
at System.Data.Entity.DropCreateDatabaseIfModelChanges`1.InitializeDatabase(TContext context)\r\n
// ... more stuff follows

上述方法的传递Image对象似乎不正确。但是,IMO,它与Winforms应用程序示例中的相同。

我错过了一些明显的东西吗?

编辑:正如评论中所建议的那样,我也提供了我的Web.config内容:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="MyConnString" connectionString="Data Source=(local);Initial Catalog=mycatalog;Integrated Security=SSPI;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings></appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
  </system.web>
  <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
</configuration>

1 个答案:

答案 0 :(得分:0)

最可能的原因是您尚未在web.config中定义这些设置:

resizedImageWidth
resizedImageHeight
croppedImageWidth
croppedImageHeight