DressingRoom

Group members: Xin Peng (xipen14)  Wonhyun Jo (wojo14)

1. Introduction

Our program is for the people to save their time. Every day, we worry about what to wear. But we don’t have enough time in the busy morning. That’s why we decided to make the application to help people’s life more effective.

There are lots of similar clothes in shops and you may have the clothes that you rarely wear. Since you can save picture of you clothes in this Application, you don’t have to waste your clothes and money no longer. You can match their clothes they have with other clothes so they don’t have to try many clothes to find matched ones. You can do this just by selecting clothes among the clothes you have. In addition, you can organize their clothes by using this application, they can remember which clothes they have. So they can save their money not to buy similar clothes. And before they buy new clothes, because they can match it by adding new images into closet, they can avoid the situation that the clothes is not matched with the clothes they already have at all. In addition, if you have clothes that you rarely wear because you think this clothes is not matched to other clothes, you can match this clothes with others easily. You may find the best matched clothes for it. Then you don’t have to throw it away.

We found an Application that can make funny face by selecting hair, eyes and nose. We could make a lots of different faces using this Application. How to use this Application is so simple and convenient. Because of this convenience and interesting feature, this Application was popular. We decided to make our Application simple. We can divide our application’s functions into three parts. First, we can add new images from albums in device or taken picture into closet or makeup section. Then we can match these things with other items in fitting room. And we can save this result of fitting room into saved images. So you can check what you matched in saved images section.

There are four sections in our Application : Fitting Room, Saved Images, Make Up and Closet. Each section does their own function. First, Make Up and Closet sections have similar functions. They show the list of images that is already uploaded into database. If you click an image of them, you can see the bigger image and the information of clothes only in Closet section. In this page, you can delete the selected image file. Also, you can upload new image files here. Especially in closet section, you can add some information of the clothes such as season, category and descriptions. These information is used in Fitting Room section. In the Fitting Room section, you can match the clothes you uploaded. When you click each part of body, it shows the images sorted by category. And among them, you can choose the image you want from them. After matching clothes, when you click the save button, it is saved into the Saved Images section.

2. Methods and materials
    During our project, we have applied many methods, which really help a lot. The following part is a brief introduction for the methods.

(1) Brainstorm: We brainstormed since our first meeting to decide what kind of app we should make. We also asked ourselves several questions:

  1.  Is it helpful to users to solve some problems in daily life?
  2.  Can we find some target users?
  3.  Is it interesting enough?
  4.  Is there any similar apps on the AppStore, or do they lack some important features?
  5.  Is that attractive to users?

We have decided our project idea after that. During the brainstorm meeting, we also get the chance to know our team members, who is good at for what. This help us cooperate in the team better.

(2) Simple prototyping: We used the simple prototyping method to design our first paper type. Before that, we have already brainstormed about the main functions that should be implemented in the app. With the ideas, we draw each designed page in small size paper, and also built the connection between pages. After this, we have formed a basic framework for the app.

(3) Evaluation: After we finish our simple prototyping, we discussed with a lot of friends, and asked them for advice. And I think in order to fully understand our design, we need to consult to different kinds of people, with different genders, ages, and different nationality. Only in that way, can we fully understand the user requirements. It makes you think from users, instead of developers.

(4) Building a first navigational digital prototype: This is our first time to design IOS interface. With the evaluations and revise for the previous paper prototype, we build our digital prototype with storyboard this time. We also watched some video on youtube about the tutorials for navigational controller. Using navigational controller, we build the connections between each app page.

(5) Evaluation:With the digital prototype, it’s much more easier to show to others about our design. We discussed with some classmates again and asked for their advice. With digital prototype, they can easily find out whether the design for buttons, functions are convenient and reasonable or not. They give us the feedback for the digital prototype function simulation, and we can revise our design according to their suggestions.

(6)Finding requirements:  We have brainstormed before for the basic requirements, but this time we need to design detailed functions according to the requirements. Some details like after create a new image, how can we save it. And some details like should we have the accessory part to make the image more complete.

(7) Implementation: We add some frameworks to satisfy our developing requirements. MVC in our design part as well as the implement ion part. We divide our classes based on their different functions in the architecture of the project. Properties and Methods are designed and realized for different functions.

We have also referred to many materials in the designing process. The BigNerd book we use in the class helps us a lot. Actually tutorials are easy to find on the website. Sometimes when we got some problems or bugs, we can always find some solution on the website: http://stackoverflow.com. It’s useful for beginners.

3. Results
    We brought the methods mentioned above and got some results.

(1) Brainstorm: we got our idea to make a dressing app, and we think it’s interesting and not that hard to realize. It’s also popular among young girls and children. People need such an app to simulate matching clothes in a short time, and it also helps them organize their closet better. And after analyzing other apps, we find many similar apps don’t get the dressing for yourself function and they can not taking pictures of your own clothes. So there is still large space for us to make such an app.

(2) Simple Prototyping: We have decided where should the functions be designed in the user interface. Through simple prototyping, we got the general idea of our app design. We got our first paper prototyping here.

Screen Shot 2014-12-22 at 6.51.35 AM—>Screen Shot 2014-12-22 at 6.51.55 AM—>Screen Shot 2014-12-22 at 6.52.04 AM—>Screen Shot 2014-12-22 at 6.52.12 AM

The main menu here we include for main functions, they are: fitting room, saved image, makeup and closet.

If we click fitting room, the app jumps to the fitting room page. There, we can select items for each part of the image, just like the second prototype page design. If we click each part, let’s say the top part, we will jump to the top selection page, where you can pick an item for the top. After match all the things for an image, u can save the image. And if you do this, you will jump to the saved image page, which is the same page with the saved image main menu.

Screen Shot 2014-12-22 at 6.52.27 AM—>Screen Shot 2014-12-22 at 6.52.34 AM–>   Screen Shot 2014-12-22 at 6.52.42 AM

If you click closet from the main menu, you will see the categorized clothes. We have filter of season and category to categorize clothes. If you click the create button on the up right side, you will jump to a create new clothes page, where some information and image for the clothes are needed. For the image, we also design the background removing function for the uploaded image to make it more fit and better looking. Click cancel button or save button, you will jump back to the closet page.

Screen Shot 2014-12-22 at 6.52.50 AM—>Screen Shot 2014-12-22 at 6.52.56 AM

Similarly, if you click makeup from the main menu, you will jump to the makeup room page. There you can view all the saved makeup. You can select them ,delete them and create a new makeup. If you click the create button, you will jump to the makeup create page, where you can upload a head image and select different hairstyle, hair color and accessories for the makeup.

(3) Evaluation: We got many value suggestions from different friends. We also have revised our prototype design to make the user interface more friendly. Some suggestions are: 1. for each create page (including create new image, clothes and makeup), the cancel button and the back to previous page button seem like have the same function, so we have decided to cancel the cancel button. 2. To make the create page better looking, we have decided to move the save button from the bottom to the upright side of the page. 3. We are also suggested to put a layer for the camera when users choose to take a picture instead of choosing existed images in album. In that way, we can only focus on the part that we want to save in the picture.

(4) Building a first navigational digital prototype: We have designed our digital prototype according to the original paper prototype, like main menu, fitting room, closet, and makeup room. We have built the basic user interface for our app. Here is our design:1

(6) Evaluations: To make all the function works, we need another class for database, which will implement all the functions including creating database, table and so on. Since we don’t have too much data to save, we can just choose to use sqlite to save the data. But we got suggestions that we have many images to handle, so it’s better to use core data or just save the key for the image. In that way, we can save more space for the database by not saving all the image data into database directly.

(7) Implementation: Besides the default frameworks included in the project, we still need the sqlite framework libsqlite3.dylib to store our data. We use MVC to design our classes. In our project, the user interface part including the buttons, the views, the labels are included in our view level. And the ViewControllers we have designed to control the views and communicate between view level and model level belong to controller level. While our data stored in database is model level.Basically, we need to implement these main functions: create new images(choose match items for each part), save and delete images, create new makeup, save and delete makeup, create new clothes, save and delete clothes.

Some core code are posted here:

Create new clothes page: In this page, we select a picture and fill out some information , then we save it to the database.

The saveClothesButtonPressed function is to describe what we do after clicking the saveClothes button. First we transfer the image need to be saved to a imageData, and then save the imageData into database. And if we open the shared database instance successfully, we will clear all the information blanks that we need to fill.

The handletap and imagePickerController function are used to implement the image-uploading function. When we create a new clothes, we need to upload a picture. If you click the image zone, imagePickerController helps us to let users to choose from a existing album or just take a picture.

#import "newClothesViewController.h"
#import "AssetsLibrary/AssetsLibrary.h"
#import "DBManager.h"

@interface newClothesViewController ()

@end

@implementation newClothesViewController
@synthesize seasonText, categoryText, descriptionText, clothesImageView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

// Save clothes

- (IBAction)saveClothesButtonPressed:(id)sender {
    
    sqlite3_int64 currentNum;

    NSData* imageData = UIImagePNGRepresentation(clothesImageView.image);

    [self dismissViewControllerAnimated:YES completion:nil];
 
    BOOL success = NO;
    success = [[DBManager getSharedInstance] saveNewClothesData:seasonText.text category:categoryText.text description:descriptionText.text imageData:imageData];
      if (success) {
        seasonText.text = @"";
        categoryText.text = @"";
        descriptionText.text = @"";
        imageData = nil;
    } else {
        NSLog(@"Fail to insert new clothes");
    }
}

// tap the imageview to take a picture or select a picture from the album

- (void)handleTap
{
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    
    picker.delegate = self;
    picker.allowsEditing = YES;
    
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
    //    picker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
        
    } else {
        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                              message:@"Device has no camera"
                                                             delegate:nil
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles: nil];
        
        [myAlertView show];
        
    }
    [self presentViewController:picker animated:YES completion:NULL];
    
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    
    UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
    self.clothesImageView.image = chosenImage;
    
    [picker dismissViewControllerAnimated:YES completion:NULL];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    
    [picker dismissViewControllerAnimated:YES completion:NULL];
    
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UIView * txt in self.view.subviews){
        if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
            [txt resignFirstResponder];
        }
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // assign tapfunction for the imageview
    UITapGestureRecognizer *singletap = [[UITapGestureRecognizer alloc]
                                         initWithTarget:self action:@selector(handleTap)];
    singletap.numberOfTapsRequired = 1;
    clothesImageView.userInteractionEnabled = YES;
    [clothesImageView addGestureRecognizer:singletap];
    


}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

The fitting room function, which will load corresponding images for each body part. The viewDidLoad function in fitting Room, each time we load this view, the corresponding part will load the selected items from the database. Take an example for the makeup, if we open the shared database instance successfully, the app will load the selected makeup imageData from database and load it in the makeup part of fitting room automatically. And it’s the same for the top, bottom, shoes and accessories parts.

//
//  fittingRoomViewController.m
//  Dress2
//
//  Created by 彭欣 on 11/6/14.
//  Copyright (c) 2014 BNR. All rights reserved.
//
#import "fittingRoomViewController.h"
#import "DBManager.h"

@interface fittingRoomViewController ()

@end

@implementation fittingRoomViewController
@synthesize makeup, top, down, shoes, accessories;


extern long makeupRow;
extern long topRow;
extern long bottomRow;
extern long shoesRow;
extern long accRow;
extern int loadCount;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    // This is for the Makeup Part to load imageView.
    BOOL successMakeup = NO;
    NSMutableArray *makeupImages = [[NSMutableArray alloc] init];
    /* get the Database instance and use the functions to get all the makeup images */
    successMakeup = [[DBManager getSharedInstance] loadAllMakeup];
    
    if(successMakeup){
        /* if load the images successfully, then we assign corresponding image to the makeup part */
        makeupImages  = [[DBManager getMakeupImageArray] copy];
        NSData *imageData = makeupImages[makeupRow];
        self.makeup.image = [UIImage imageWithData:imageData];
    }
    /* Similar functions are realized for the top, bottom, shoes and accessory part */
    
    BOOL successTop = NO;
    NSMutableArray *topImages = [[NSMutableArray alloc] init];
    successTop = [[DBManager getSharedInstance] loadAllTops];
    if(successTop){
        topImages  = [[DBManager getTopImageArray] copy];
        NSData *imageData = topImages[topRow];
        self.top.image = [UIImage imageWithData:imageData];
    }
  
    BOOL successBottom = NO;
    NSMutableArray *bottomImages = [[NSMutableArray alloc] init];
    successBottom = [[DBManager getSharedInstance] loadAllBottoms];
    if(successBottom){
        bottomImages  = [[DBManager getBottomImageArray] copy];
        NSData *imageData = bottomImages[bottomRow];
        self.down.image = [UIImage imageWithData:imageData];
    }
    BOOL successShoes = NO;
    NSMutableArray *shoesImages = [[NSMutableArray alloc] init];
    successShoes = [[DBManager getSharedInstance] loadAllShoes];
    if(successShoes){
        shoesImages  = [[DBManager getShoesImageArray] copy];
        NSData *imageData = shoesImages[shoesRow];
        self.shoes.image = [UIImage imageWithData:imageData];
    }
    
    BOOL successAcc = NO;
    NSMutableArray *accImages = [[NSMutableArray alloc] init];
    successAcc = [[DBManager getSharedInstance] loadAllAccs];
    if(successAcc){
        accImages  = [[DBManager getAccImageArray] copy];
        NSData *imageData = accImages[accRow];
        self.accessories.image = [UIImage imageWithData:imageData];
    }
}
    



- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

We have also loaded our code to bitbucket:

https://wonhyun11@bitbucket.org/iosprogrammingsdu/dressroom.git

Here is our video demonstrating

:

4. Discussion

We completed to make basic functions that we supposed to make. You can save pictures of clothes or faces and it sorts clothes according to the information you typed. You can select type of your clothes for convenient use. When you upload your new clothes, you can type the category of it. For example, if you type your clothes as a top, it is only shown at the top part when you use the Fitting Room section. So you don’t have to see all of your clothes you have when choosing one part.

To sort the clothes, however, you need to type the category correctly same because it doesn’t provide check box option. This can be inconvenient for users.

We couldn’t implement some details that can make our Application better. We supposed to make a function that can erase background of picture before saving the selected picture. But we couldn’t find the method. If it can erase the background, the result of Fitting Room would look much better. And we wanted to sort the clothes more variously. Our purpose is to show the clothes on Closet section differently according to the season or category. But we are not used to using database and collectionView, we couldn’t make it. If it can sort clothes more variously, it is more convenient to use. Because you don’t need to check your summer clothes during winter.

You can delete your pictures if you don’t want it to be shown in the Application anymore. If you touch the picture in the list, it shows bigger picture in new view. Then you can delete or check the information of picture. But we don’t provide modifying function. So if you want to change the information of it, you should delete it first and then add new one with new information.

Because we designed the database table with column for imagedata, the Application doesn’t make new folders in your device album. Then you don’t be annoyed. The data of our Application would not be shown in the Camera Album. However, since we store imagedata into database, the time to load the image can be long if there are lots of images.

We showed this Application to our friends. Most of them are girls. Because we thought they are the best potential user for this Application. They said this Application is easy to use and it would be efficient in the morning. Because they don’t have to waste time to match many clothes. But they said it is inconvenient to add new clothes. Since they have to type the category by themselves. And they also said it is interesting to match clothes easily. In addition, they said the matched clothes are not good-looking because they have background. Also, they pointed out that since it just have only one section for top, they can’t match the t-shirt with jacket.

Their general opinions are it is easy to use and interesting. But some of features are inconvenient. Reflecting this opinions, we can provide a better Application for them.

 

Reference:

[1] Conway, Joe, and Aaron Hillegass. iPhone programming: the Big Nerd Ranch guide. Addison-Wesley Professional, 2010.

[2]Neuburg, Matt. Programming iOS 5: Fundamentals of iPhone, iPad, and iPod touch Development. ” O’Reilly Media, Inc.”, 2012.

[3] Martin, Robert Cecil. Designing object-oriented C++ applications. Prentice Hall, 1995.

Leave a Reply