Send UIImage to LocalwebServer using GCDWebServer
Asked Answered
N

4

14

My app using GCDWebServer I get a photo from my iPhone album by using AssetsLibrary and I store them in NSDocumentDirectory. I just want to get access Url to this photo to show them in a web page.

There is my code :

[_webServer addHandlerForMethod:@"POST"
                              path:@"/"
                      requestClass:[GCDWebServerURLEncodedFormRequest class]
                      processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {

                          ALAsset *asset = [self.arrayPictures objectAtIndex:0];
                          ALAssetRepresentation *rep = [asset defaultRepresentation];
                          CGImageRef iref = [rep fullResolutionImage];
                          UIImage *thumbnail = [UIImage imageWithCGImage:iref];
                          NSString* path ;
                          if (thumbnail != nil)
                          {
                              NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
                              NSString *documentsDirectory = [paths objectAtIndex:0];
                               path =  [[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:@"test.png"]];
                              NSData* data = UIImagePNGRepresentation(thumbnail);
                              [data writeToFile:path atomically:YES];
                          }

                          NSURL *url = [NSURL fileURLWithPath:path];
                          NSString* html = [NSString stringWithFormat:@"<html><body><img src=\"%@\" width=\"400\" height=\"500\"/></body></html>", url];
                          return [GCDWebServerDataResponse responseWithHTML:html];

                      }];
Neff answered 3/2, 2015 at 16:23 Comment(0)
S
5

For DocumentDirectory path

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagePath = [[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:@"test.jpg"]];
NSURL *baseURL2 = [NSURL fileURLWithPath:documentsDirectory];
NSString* html2 = [NSString stringWithFormat:@"<html><body><img src=\"%@\" width=\"400\" height=\"500\"/></body></html>", imagePath];

[_webView loadHTMLString:html2 baseURL:baseURL2];

For Bundled resource

NSString *path = [[NSBundle mainBundle] pathForResource:@"ahsan" ofType:@"jpg"]; // path to your image source.

NSURL *baseURL = [NSURL fileURLWithPath:path];

NSString* html = [NSString stringWithFormat:@"<html><body><img src=\"%@\" width=\"400\" height=\"500\"/></body></html>", path];
Sloganeer answered 17/4, 2015 at 9:38 Comment(1)
above method for load image from document directory only working in simulator, not in a real device :(Bedspring
M
4

Try this code.

GCDWebServer* webServer = [[GCDWebServer alloc] init];
[webServer addGETHandlerForBasePath:@"/" directoryPath:[[NSBundle mainBundle] bundlePath] indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
[webServer runWithPort:8080];
Melentha answered 17/4, 2015 at 10:9 Comment(0)
A
2

Looks like nobody is answering the actual question here: this is not about uploading a photo from iOS to a web server or viewing it in a local UIWebView, but about serving that photo using GCDWebServer so that users can view it by connecting to the device using a web browser e.g. by going to http://my-device.local/photo-1234.jpg.

The sample code you provided has 2 major issues:

  • You are creating a handler for POST requests while you need to handle GET requests (POST is when submitting forms from web browsers, while GET is for regular web browsing and getting web pages).
  • Instead of returning the image data, you are returning an HTML webpage, which contains a URL to the image file locally (e.g. file:///some/path/photo-1234.jpg) instead of HTTP URL handled by GCDWebServer (e.g. http://my-device.local/photo-1234.jpg). File URLs do not make sense outside of the device itself and will not work.

If you have all the photos as files in your documents folder, you can simply add a GET handler to GCDWebServer to serve the contents of the entire documents folder:

[webServer addGETHandlerForBasePath:@"/"
                      directoryPath:<PATH_TO_DOCUMENTS_DIRECTORY>
                      indexFilename:nil
                           cacheAge:3600
                 allowRangeRequests:YES];

This is not a very good solution though, as it requires copying photos from the assets library into the documents folder, which is wasteful. Instead, consider dynamically serving the photo assets as I explain in my answer to a related question here: https://mcmap.net/q/831248/-convert-ios-photo-album-path-url-same-like-as-document-directory-file-path.

Accipitrine answered 3/8, 2015 at 2:51 Comment(4)
Nice explanation!Finny
How to generate Public IP address URL? I am facing one problem here, I have stored export.mov video in documents(iOS) directory. I get server base URL using webServer.serverURL which points to documents directory. But this gives me URL with internal IP address like eg. 192.168.1.129:8080/export.mov , which works from local machine browser, however does not work in other machine's browsers which are also connected in the same network.Finny
@Finny That's a networking problem, not a GCDWebServer one. Maybe port 8080 is blocked on your network?Accipitrine
@Finny - could share code snippet as mentioned above, you were able to host the video ?Georgie
A
1

You can create one GET request which will return all custom URLs of the photo assets.

After that create one handler of that custom URLs which will return requested URL image Data.

In a custom URL handler use below code

//Get PHAsset image name with extionsion.
let filename = NSURL(string: (asset as! PHAsset).originalFilename!)

// Retrive image data from PHAsset object
PHImageManager.default().requestImageData(for: asset as! PHAsset, options: nil, resultHandler: { (imageData, str, nil, info) in

    //Check imageData is nil or not.
    if (imageData) {

        //Return image Data with contentType
        let imageDatas = UIImagePNGRepresentation(imageData)

        completionBlock!(GCDWebServerDataResponse(data: imageDatas, contentType: "image/\((filename?.pathExtension)!)"))
    } else {

        // Image retrive error message return.
        let jsonResponse = ["type":"failed","Message":"Image not avilable."] as [String : Any]
        completionBlock!(GCDWebServerDataResponse(jsonObject: jsonResponse))
    }
})

// MARK:- Get File name from PHAsset.
extension PHAsset {

    var originalFilename: String? {

        var fname:String?

        if #available(iOS 9.0, *) {
            let resources = PHAssetResource.assetResources(for: self)
            if let resource = resources.first {
                fname = resource.originalFilename
            }
        }

        if fname == nil {
            // this is an undocumented workaround that works as of iOS 9.1
            fname = self.value(forKey: "filename") as? String
        }

        return fname
    }
}
Alienation answered 9/7, 2017 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.