简体   繁体   English

存储与项目相关的图片的好方法是什么?

[英]What's a good way to store project related pictures?

I'm trying to get an array of PictureBox to display a list of pictures (in png file format). 我正在尝试获取一个PictureBox数组以显示图片列表(以png文件格式)。

I tried to use the .NET ImageList control but it insists in re-sizing my pictures. 我尝试使用.NET ImageList控件,但它坚持要调整图片大小。 It also does not support transparent background of those png files. 它还不支持这些png文件的透明背景。

I also tried to use the Assembly to retrieve my files like this: 我还尝试使用Assembly来检索我的文件,如下所示:
_imageStream = _assembly.GetManifestResourceStream("MyNamespace.MyImage.png"); but the code does not return me any resource files nor does it throw any run-time error. 但是代码不会向我返回任何资源文件,也不会引发任何运行时错误。

My question is, is there any other ways to do this? 我的问题是,还有其他方法吗? Or better yet, can I somehow make the ImageList control to NOT alter my picture? 还是更好,我能以某种方式使ImageList控件不改变我的图片吗? Thanks. 谢谢。

You can try something like this although I am not sure that this is the best one or not:- 您可以尝试这样的方法,尽管我不确定这是否是最好的方法:-

 Assembly ambly = Assembly.LoadFile(pathToDll);

or 要么

 BitMap bitMap;
 // where "ns" is the default namespace of the resource project    
 using (Stream resourceStream = ambly.GetManifestResourceSream("ns.image.jpg"))
 {
  bitMap = BitMap.FromStream(resourceStream);
 }

An example:- 一个例子:-

 interface IThemeResourceProvider
 {
 Stream LoadBigLogo();
 Stream LoadSmallLogo();
 } 

Then implement that interface in your resource library 然后在您的资源库中实现该接口

 public class ThemeResourceProvider : IThemeResourceProvider
 {
 public Stream LoadBigLogo()
 {
     Assembly ambly = Assembly.GetExecutingAssembly();
     return ambly.GetManifestResourceStream("namespace.image.jpg");
  }

  (...)
  }

Finally, instead of loading the resource directly in your main application, you instantiate the IThemeResourceProvider found in the resource library 最后,您可以实例化在资源库中找到的IThemeResourceProvider,而不是直接在主应用程序中加载资源。

    Assembly assembly = Assembly.LoadFile(pathToDll);

   var results = from type in assembly.GetTypes()
           where typeof(IThemeResourceProvider).IsAssignableFrom(type)
           select type;

Now you have an IEnumerable in that list. 现在,该列表中有一个IEnumerable。 Typically, you'd only have one, but using this approach you could also host multiple sets of resources, and implement multiple IThemeResourceProviders in the same resource dll. 通常,您只有一个,但是使用这种方法,您还可以托管多组资源,并在同一资源dll中实现多个IThemeResourceProviders。 You could eg identify each IThemeResourceProvider with a name, either as a property, or using a custom [Attribute] decoration on your various implementations. 例如,您可以使用名称标识每个IThemeResourceProvider,将其作为属性,或在各种实现中使用自定义的[Attribute]装饰。 I'll leave the rest up to you to figure out. 我把剩下的交给你去解决。

But here's how to instantiate the IThemeResourceProviders in your list 但是,这是在您的列表中实例化IThemeResourceProviders的方法

    foreach (var providerType in results)
   {
  var constructorInfo = providerType.GetConstructor(Type.EmptyTypes);
  IThemeResourceProvider provider = constructorInfo.Invoke(null);
   }

And finally, using one of these providers to get a bitmap: 最后,使用以下提供程序之一获取位图:

  BitMap bitMap;
  using (Stream resourceStream = provider.LoadBigLogo())
  {
   bitMap = BitMap.FromStream(resourceStream);
  }

This is the code that I got from someone and it's worked well for me! 这是我从某人那里获得的代码,对我来说效果很好!

    private void SetImage(PictureBox pb) {
        try {
            Image img = pb.Image;

            Size imgSize = GenerateImageDimensions( img.Width, img.Height, pb.Width, pb.Height );
            Bitmap finalImg = new Bitmap( img, imgSize.Width, imgSize.Height );
            Graphics gfx = Graphics.FromImage( img );
            gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            pb.Image = null;
            pb.SizeMode = PictureBoxSizeMode.AutoSize;
            pb.Image = finalImg;
        } catch(Exception ex) {

        }
    }
    public Size GenerateImageDimensions(int currW, int currH, int destW, int destH) {
        //double to hold the final multiplier to use when scaling the image
        double multiplier = 0;

        //string for holding layout
        string layout;

        //determine if it's Portrait or Landscape
        if(currH > currW) layout = "portrait";
        else layout = "landscape";

        switch(layout.ToLower()) {
            case "portrait":
                //calculate multiplier on heights
                if(destH > destW) {
                    multiplier = (double) destW / (double) currW;
                } else {
                    multiplier = (double) destH / (double) currH;
                }
                break;
            case "landscape":
                //calculate multiplier on widths
                if(destH > destW) {
                    multiplier = (double) destW / (double) currW;
                } else {
                    multiplier = (double) destH / (double) currH;
                }
                break;
        }

        //return the new image dimensions
        return new Size( (int) (currW * multiplier), (int) (currH * multiplier) );
    }

EDIT: Full disclosure all my images are jpg so I have no clue how this will hand transparent backgrounds. 编辑:完全披露我所有的图像都是jpg,所以我不知道这将如何处理透明背景。

EDIT TWO: Also you will need to adjust the pb.SizeMode to fit your needs. 编辑pb.SizeMode :同样,您将需要调整pb.SizeMode以适合您的需求。 The way I did it was to set a max size for the PictureBox and it's worked well. 我这样做的方法是为PictureBox设置最大大小,并且效果很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM