相同的图像大小调整和图像裁剪功能在 Winforms 应用中有效,而在同一解决方案的 Webapi 应用中不起作用



简短介绍:我有这个解决方案,该解决方案由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)rn
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)rn
at My_API.Util.Helper.ResizeImage(Image imgToResize, Size size) in D:\Path\To\MyApp\My_API\Util\Helper.cs:line 42rn
at My_API.DAL.InitDb.GenerateThumbnailImage(Image originalImage) in D:\Path\To\MyApp\My_API\DAL\MyDbContext.cs:line 341rn
at My_API.DAL.InitDb.PerformInitSetup(MyDbContext _ctx) in D:\Path\To\MyApp\My_API\DAL\MyDbContext.cs:line 176rn
at My_API.DAL.InitDb.Seed(MyDbContext _ctx) in D:\Path\To\MyApp\My_API\DAL\MyDbContext.cs:line 67rn
at System.Data.Entity.DropCreateDatabaseIfModelChanges`1.InitializeDatabase(TContext context)rn
// ... more stuff follows

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

我错过了明显的东西吗?

编辑:正如评论中建议的那样,我还提供了我的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>

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

resizedImageWidth
resizedImageHeight
croppedImageWidth
croppedImageHeight

最新更新