Arrays 从文件夹中的图像创建一个数组,并随机呈现给定数量的图像(Objective-C)

Arrays 从文件夹中的图像创建一个数组,并随机呈现给定数量的图像(Objective-C),arrays,objective-c,image,Arrays,Objective C,Image,我试图从包含大量图像(120)的文件夹中随机显示预先指定数量的.PNG图像(例如20) 下面是我的代码,基于我能找到的几个例子;我在viewDidLoad中调用此方法 -(void)displayImagesInRandomOrder { // Obtain set number of attempts imageArrayLength = 20; // arbitrary choice in this example // Build array from

我试图从包含大量图像(120)的文件夹中随机显示预先指定数量的.PNG图像(例如20)

下面是我的代码,基于我能找到的几个例子;我在viewDidLoad中调用此方法

-(void)displayImagesInRandomOrder {

    // Obtain set number of attempts
    imageArrayLength = 20; // arbitrary choice in this example
    
    // Build array from all (120) .PNG images in folder
    NSArray *_imageArray = [[NSBundle mainBundle] pathsForResourcesOfType:@".png" inDirectory:@"(Folder directory)/."];

    // Create a random integer for each of the (120) images in the array
    int randomIndex = arc4random_uniform((uint32_t) _imageArray.count);
    
    // Select an image from the array using the random number
    UIImage *randomImage = [_imageArray objectAtIndex:randomIndex];
    
    // Add the UIImage to a UIImageView and display it on the screen
    UIImageView *tempImageView = [[UIImageView alloc] initWithImage:randomImage];
    
    // Set position of the image
    tempImageView.contentMode = UIViewContentModeScaleAspectFit;

}
所有的帮助/建议都被亲切地接受了,因为我已经盯着这个太久了。非常感谢:)

编辑//

以下是我修改后的第一个方法,用于构建从文件夹中随机选择的20幅图像的数组:

NSMutableArray *imageQueue;

- (void)buildArrayOfRandomImages {
    
    // Build array of pathnames to images in folder
    NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:@"(Folder directory)"];
    
    // Obtain preset number of attempts
    imageQueueLength = 20;
    
    // Create image queue (new array) of predetermined length

    // use a loop to add correct number of images to image queue  
    for(int i = 1; i <= imageQueueLength; i++) {

        // Select an integer at random for each image in the array of pathnames
        int randomIndex = arc4random_uniform((uint32_t) [pathArray count]);

        // Add images to the image queue
        [imageQueue arrayByAddingObject:[UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]]];
    }
}
NSMutableArray *imageQueue;

我确信这会起作用,但通过
buildArrayOfRandomImages
方法,imageQueue数组仍然是空的。

让我们看看是否可以帮助您:

这将生成一个路径数组(请参见)。运行代码时,此数组的值是多少?找到任何路径了吗

您有一个路径数组,索引它不会生成
UIImage
。阅读在
UIImage
中创建图像对象

这里没有选择20个元素的代码。当你想从一副扑克牌中随机选择N张不同的牌时,你怎么做?现在阅读
NSArray
。。。嗯


评论和问题编辑后的附录

你已经取得了一些好的进展,但正如你所说,它仍然不起作用。让我们看看你的新代码:

以下是我修改后的第一个方法,用于构建从文件夹中随机选择的20幅图像的数组:

NSMutableArray *imageQueue;

- (void)buildArrayOfRandomImages {
    
    // Build array of pathnames to images in folder
    NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:@"(Folder directory)"];
    
    // Obtain preset number of attempts
    imageQueueLength = 20;
    
    // Create image queue (new array) of predetermined length

    // use a loop to add correct number of images to image queue  
    for(int i = 1; i <= imageQueueLength; i++) {

        // Select an integer at random for each image in the array of pathnames
        int randomIndex = arc4random_uniform((uint32_t) [pathArray count]);

        // Add images to the image queue
        [imageQueue arrayByAddingObject:[UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]]];
    }
}
NSMutableArray *imageQueue;
这里有两个问题,一个设计,一个编程:

  • 切勿使用全局变量仅从方法返回值
  • 这声明了一个变量,
    imageQueue
    ,它能够存储对
    NSMutableArray
    的引用。需要创建所有对象,您不需要在此处创建数组,此变量的值为
    nil
    ——即,它不引用任何内容
  • 尝试以下设计:

    - (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength
    {
       // create a mutable array to hold the images
       NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
    
       // your code to fill the array
       ...
    
       // return the final array, by convention immutable (NSArray) so copy
       return [imageQueue copy];
    }
    
    回到您的代码:

    这本身没有什么问题,但是您是否检查过(使用调试器或日志语句)pathArray是否包含任何元素?虽然
    (文件夹目录)
    是文件夹的有效名称,但实际上您是否将文件夹命名为该名称

    这不是你所期望的。方法
    arrayByAddingObject:
    来自
    NSArray
    ,它从现有数组和新元素创建一个新的
    NSArray
    ,然后该方法返回这个新数组。此代码忽略返回值,因此丢弃新数组

    但是,您没有
    NSArray
    ,而是
    NSMutableArray
    ,因此无需在每次需要向可变数组添加对象时创建新数组。再次查看
    NSMutableArray

    这里是第二种方法:

    - (void)displayImageFromArray {
    
        // Add the UIImage to a UIImageView and display it on screen
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[imageQueue objectAtIndex:imageCount]];
        
        // Set screen position of image
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        
        // increment count every time method is called
        imageCount++;
    }
    
    - (void)displayImageFromArray {
    
       // Add the UIImage to a UIImageView and display it on screen
       UIImageView *imageView = [[UIImageView alloc] initWithImage:[imageQueue objectAtIndex:imageCount]];
       
       // Set screen position of image
       imageView.contentMode = UIViewContentModeScaleAspectFit;
       
       // increment count every time method is called
       imageCount++;
    }
    
    首先,此方法应具有如下声明:

    - (void) displayImage:(NSUInteger)imageCount fromArray:(NSArray *)imageQueue
    
    i、 e.传入所需的数据,不要使用全局变量。或者更好的是:

    - (void) displayImage:(UIImage)theImage
    
    因为不需要传递数组和索引,如果以这种方式定义,则图像根本不需要来自数组

    但是,上面的声明可能不够充分——您编写的方法不会显示任何图像,而要显示图像所需的附加代码也可能需要进一步的参数

    为什么它不显示任何图像?
    UIImageView
    仅当其是当前视图层次结构的一部分时,才会在屏幕上显示其图像。这本身就是另一个完整的主题,所以除非为了简洁而省略了代码,否则您还有更多的阅读要做


    Postscript


    不要试图进一步扩展这个问题,这不是它的工作原理。如果在研究和设计新解决方案时遇到了问题,请针对新问题提出新问题。您可以包括对该问题的引用,以便帮助您的人可以追溯历史。

    @CRD,根据要求,我不再更新该问题,但想向您展示我的进度。再次感谢你让我走了这么远

    [正如您明智地建议的,我将此线程限制为创建随机选择的图像阵列,因为显示它们是一个完全不同的问题。]

    解决方案1(似乎有效,但不雅观):

    解决方案3:(避免导入
    GameplayKit
    ,方法是使用单独的数组洗牌方法,主要基于以下内容:,该方法本身基于@CRD推荐的Fisher–Yates洗牌)

    -(NSArray*)BuildArrayOradomImageSwithLength:(nsInteger)imageQueueLength{
    //为文件夹中的图像生成路径名数组
    NSString*目录=nil;
    NSArray*pathArray=[[NSBundle bundleForClass:[self class]]PathsForResourceSoftType:@“png”目录:目录];
    //创建pathArray的无序副本
    NSArray*随机路径;
    ShuffledPath=[self-shuffleArray:pathArray];
    //q创建一个可变数组来保存图像
    NSMutableArray*imageQueue=[NSMutableArray阵列容量:imageQueueLength];
    //使用路径名填充映像队列数组
    
    对于(i=1;我感谢您,@CRD。我将通读您提到的文档并返回我的进度。祝您好运,因此我通读了文档并意识到我错过的一个逻辑步骤。我想我需要基于(120)创建一个包含20个图像的新数组从文件夹中获取的路径名。我已决定将原始方法拆分为两个,第一个方法我希望创建包含20个随机图像的“图像队列”数组(请参见对上述问题的编辑)。再次感谢您在这方面的帮助!我有一些阅读要做:)好吧,根据你的建议,我成功地通过循环填充了imageQueue数组;非常感谢你让我走到了这一步,因为我真的被卡住了
           // Add images to the image queue
           [imageQueue arrayByAddingObject:[UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]]];
       }
    }
    
    - (void)displayImageFromArray {
    
       // Add the UIImage to a UIImageView and display it on screen
       UIImageView *imageView = [[UIImageView alloc] initWithImage:[imageQueue objectAtIndex:imageCount]];
       
       // Set screen position of image
       imageView.contentMode = UIViewContentModeScaleAspectFit;
       
       // increment count every time method is called
       imageCount++;
    }
    
    - (void) displayImage:(NSUInteger)imageCount fromArray:(NSArray *)imageQueue
    
    - (void) displayImage:(UIImage)theImage
    
    - (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength {
        
        // Build array of pathnames to images in folder (nil directory was the only one that actually worked for me)
        NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:nil];
        
        // Create a mutable array to hold the images
        NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
        
        // Fill the imageQueue array using pathnames
        for(int i = 1; i <= imageQueueLength; i++) {
            // Select a random integer
            int randomIndex = arc4random_uniform((uint32_t) [pathArray count]);
            // Use the random integer to select a pathname and create an image object
            UIImage *image = [UIImage imageWithContentsOfFile:[pathArray objectAtIndex:randomIndex]];
            // Ensure all elements are unique
            if (![imageQueue containsObject:image]) {
               // Add image to the image queue
               [imageQueue addObject:image];
            } else {
               i--; // ensure the array is the correct length
            }
        }
        // Return the final array, by convention immutable (NSArray) so copy
        return [imageQueue copy];
    }
    
    
    - (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength {
        // Build array of pathnames to images in folder
        NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:nil];
        
        //Create a shuffled copy of pathArray
        NSArray *shuffledPaths;
        shuffledPaths = [pathArray shuffledArray];
        
        // Create a mutable array to hold the images
        NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
    
        // Fill the image queue array using pathnames
        for(NSUInteger i = 1; i <= imageQueueLength; i++) {   
        UIImage *image = [UIImage imageWithContentsOfFile:[shuffledPaths objectAtIndex:(i - 1)]];
            [imageQueue addObject:image];
        }
        // Return the final array, by convention immutable (NSArray) so copy
        return [imageQueue copy];
    }
    
    - (NSArray *) buildArrayOfRandomImagesWithLength:(NSUInteger)imageQueueLength {
        // Build array of pathnames to images in folder
        NSString *directory = nil;
        NSArray *pathArray = [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:@"png" inDirectory:directory];
        
        //Create a shuffled copy of pathArray
        NSArray *shuffledPaths;
        shuffledPaths = [self shuffleArray:pathArray];
        
        // qCreate a mutable array to hold the images
        NSMutableArray *imageQueue = [NSMutableArray arrayWithCapacity:imageQueueLength];
        // Fill the image queue array using pathnames
        for(NSUInteger i = 1; i <= imageQueueLength; i++) {
            UIImage *image = [UIImage imageWithContentsOfFile:[shuffledPaths objectAtIndex:(i - 1)]];
            [imageQueue addObject:image];
        }
        // Return the final array, by convention immutable (NSArray) so copy
        return [imageQueue copy];
    }
    
    - (NSArray *) shuffleArray:(NSArray*)array {
        NSMutableArray *shuffledArray = [NSMutableArray arrayWithArray:array];
        
        for (NSUInteger i = 0; i < [shuffledArray count] - 1; ++i) {
            NSInteger remainingCount = [shuffledArray count] - i;
            NSInteger exchangeIndex = i + arc4random_uniform((u_int32_t )remainingCount);
            [shuffledArray exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];
        }
        return [shuffledArray copy];
    }