juce_ios_ImagePicker

juce_ImagePicker.h

[code]/*

This file is part of the JUCE library - "Jules’ Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.


JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.

JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.


To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.

==============================================================================
*/

#ifndef JUCE_IMAGE_PICKER_JUCEHEADER
#define JUCE_IMAGE_PICKER_JUCEHEADER
#if JUCE_IOS

class JUCE_API ImagePicker
{
public:
ImagePicker();
~ImagePicker();

//==============================================================================
enum Orientation
{
    Up,            // default orientation
    Down,          // 180 deg rotation
    Left,          // 90 deg CCW
    Right,         // 90 deg CW
    UpMirrored,    // as above but image mirrored along other axis. horizontal flip
    DownMirrored,  // horizontal flip
    LeftMirrored,  // vertical flip
    RightMirrored, // vertical flip
};

//==============================================================================
class JUCE_API  Listener
{
public:
    /** Destructor. */
    virtual ~Listener() {}
    
    virtual void imagePickerFinished (const Image& image, Orientation orientation) = 0;
    virtual void imagePickerCanceled()  {}
};

void addListener (Listener* newListener);
void removeListener (Listener* listener);

//==============================================================================
void show();

//==============================================================================
void saveToPhotosAlbum (const Image& imageToSave);

//==============================================================================
/**	@internal */
void sendImagePickerFinishedMessage (void* picker, void* info);

/**	@internal */
void sendImagePickerCanceledMessage (void* picker);

private:
ListenerList listeners;
Orientation orientation;

//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImagePicker);

};

#endif
#endif // JUCE_IMAGE_PICKER_JUCEHEADER
[/code]

juce_ios_ImagePicker.mm

[code]/*

This file is part of the JUCE library - "Jules’ Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.


JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.

JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.


To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.

==============================================================================
*/

END_JUCE_NAMESPACE

//==============================================================================
@interface JuceUIImagePicker : UIImagePickerController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
@private
juce::ImagePicker* owner;
}

@end

@implementation JuceUIImagePicker

  • (id) initWithOwner: (juce::ImagePicker*) owner_
    {
    if ((self = [super init]) != nil)
    {
    owner = owner_;

      self.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
      self.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeSavedPhotosAlbum];
      self.allowsEditing = NO;
      self.delegate = self;
    

    }

    return self;
    }

  • (void) dealloc
    {
    [super dealloc];
    }

  • (void) imagePickerController: (UIImagePickerController*) picker didFinishPickingMediaWithInfo: (NSDictionary*) info
    {
    owner->sendImagePickerFinishedMessage (self, info);
    }

  • (void) imagePickerControllerDidCancel: (UIImagePickerController*) picker
    {
    self.delegate = nil;
    owner->sendImagePickerCanceledMessage (self);
    }

  • (UIViewController*) topLevelViewController
    {
    UIResponder* responder = ((UIView*) [[UIApplication sharedApplication].keyWindow.subviews objectAtIndex: 0]).nextResponder;

    if ([responder isKindOfClass: [UIViewController class]])
    {
    return (UIViewController*) responder;
    }

    return nil;
    }
    @end

BEGIN_JUCE_NAMESPACE

//==============================================================================
ImagePicker::ImagePicker()
: orientation (Up)
{

}

ImagePicker::~ImagePicker()
{

}

//==============================================================================
void ImagePicker::addListener (Listener* const newListener)
{
listeners.add (newListener);
}

void ImagePicker::removeListener (Listener* const listener)
{
listeners.remove (listener);
}

//==============================================================================
void ImagePicker::show()
{
UIViewController* controller = [JuceUIImagePicker topLevelViewController];

if (controller != nil)
{
    JuceUIImagePicker* imagePicker = [[JuceUIImagePicker alloc] initWithOwner: this];
    [controller presentModalViewController: imagePicker animated: YES];
}

}

//==============================================================================
void ImagePicker::saveToPhotosAlbum (const Image& imageToSave)
{
JPEGImageFormat jpgff;
MemoryOutputStream mos;
jpgff.writeImageToStream (imageToSave, mos);

UIImage* im = [UIImage imageWithData: [NSData dataWithBytes: mos.getData() length: mos.getDataSize()]];
im = [UIImage imageWithCGImage: im.CGImage scale: 1.0f orientation: (UIImageOrientation) orientation];
UIImageWriteToSavedPhotosAlbum (im, nil, nil, nil);

}

//==============================================================================
void ImagePicker::sendImagePickerFinishedMessage (void* picker_, void* info)
{
UIViewController* controller = [JuceUIImagePicker topLevelViewController];

if (controller != nil)
{
    [controller dismissModalViewControllerAnimated: YES];
    
    JuceUIImagePicker* imagePicker = (JuceUIImagePicker*) picker_;
    [imagePicker release];
}

NSDictionary* dictionary = (NSDictionary*) info;

NSString* mediaType = [dictionary objectForKey: UIImagePickerControllerMediaType];
UIImage* originalImage = nil;

if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) 
{
    originalImage = (UIImage*) [dictionary objectForKey: UIImagePickerControllerOriginalImage];
}

if (CFStringCompare ((CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo)
{
    // Intentionally empty..
}

NSData* data = UIImageJPEGRepresentation (originalImage, 0.0f);
Image im = ImageFileFormat::loadFrom (data.bytes, data.length);
orientation = (Orientation) originalImage.imageOrientation;
listeners.call (&Listener::imagePickerFinished, im, orientation);

}

void ImagePicker::sendImagePickerCanceledMessage (void* picker_)
{
UIViewController* controller = [JuceUIImagePicker topLevelViewController];

if (controller != nil)
{
    [controller dismissModalViewControllerAnimated: YES];
    
    JuceUIImagePicker* imagePicker = (JuceUIImagePicker*) picker_;
    [imagePicker release];
}

}[/code]

This is still work in progress, and feels like it needs to be an iOS FileChooser implementation;

Some questions:

Does Jules have permission to include this code as part of the commercially licensed / paid distribution of Juce or is it strictly GPLed?

Are you transferring all rights and ownership of this code to Raw Material Software?

Yes on “permission to include this code as part of the commercially licensed”, though I doubt Jules would want to include this, he’ll probably make something better anyway.

Yes.

I’m not very versed in this whole commingling licenses business, I’ve put this up for people to use with the JUCE library, it is the only way that it can be used really, so whatever licence applies to JUCE applies to this and vice versa I guess. Need more research…

I did see your brief discussion on this:
http://www.rawmaterialsoftware.com/viewtopic.php?f=6&t=8494
and it will indeed get interesting as new JUCE modules surface, I’m planning to do a “mobile” module project with stuff like ImagePicker, MapKit, TwitterAPI, Camera etc… It would be nice if Jules can set some ground rules on what to include/exclude from the copyright notice

Also I probably shouldn’t name these file(s)/post(s) “juce_xxx” but this is what I do here on my end…

-Thanks

[size=150][color=#FF0000]DISCLAIMER: I am not a lawyer, this is not legal advice.
[/color][/size]

Its up to you to decide how you want to license it. There are two broad categories of choice:

GNU GPL v2

This lets anyone use your code, but they cannot use it in proprietary software. Jules would not be able to include it as part of the commercial distribution of Juce.

MIT License

Anyone can use your code, including proprietary software. This by definition includes the commercial distribution of Juce.

You said you want to transfer ownership to Raw Material Software but I don’t think that is possible. From my limited knowledge, you and Jules would have to sign an agreement that transfers the rights to Raw Material Software. As it stands now, your source file contribution makes use of the Juce trademark in a way that suggests that someone other than Raw Material Software has published a portion of Juce.

If Jules were to let it slide, and more people started doing this, it would dilute the Juce trademark. One could argue this leads to “naked licensing”:

http://www.ivanhoffman.com/naked.html

I think the important question, is whether or not you are OK with someone using your code in a proprietary piece of software (i.e. the source code is private). If you are OK with it, then mark your code as MIT licensed. If you are not OK with it, then mark it as GPL. Me personally I use the MIT license, and this is what I put at the top of my files:

/*******************************************************************************
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
Copyright (c) 2009 by Vincent Falco

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*******************************************************************************/

If you don’t want to allow proprietary use, then follow the directions for applying the GPL v2 to your sources:

http://www.gnu.org/licenses/gpl-2.0.html#SEC4

From what I understand MIT is the way to go then… There’s also CC0 (Creative Commons). http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses

Thanks for the info.

While the Creative Commons license is certainly compatible in terms of usage, the MIT license requires that the copyright, author, and license notice remain intact - which I definitely want. Although I am contributing my code for unlimited commercial or non-commercial usage, I definitely don’t want anyone else running around claiming that they wrote it. Plus the MIT license is shorter.

All you would have to write is

Super JUCE Module by Firstname Lastname is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/
including the link to the cc license.

Generate it here.
http://creativecommons.org/choose/

I like it because you have choice in configuring the licence.

http://creativecommons.org/licenses/by/3.0/legalcode

4. Restrictions. You must keep intact all notices that refer to this License

[quote=“aiit”]http://creativecommons.org/licenses/by/3.0/legalcode

4. Restrictions. You must keep intact all notices that refer to this License[/quote]

You’re making a strong case!!

never-mind…
http://wiki.creativecommons.org/FAQ#Can_I_use_a_Creative_Commons_license_for_software.3F

They don’t recommend it.

This was working very well with JUCE 2.0.21 (thanks!) but with the “bleeding edge” version the image picker hangs when attempting to be shown…

I’ve put this on github here:

That’s definitely more updated code. I’ll have a look and double check if all still works with the latest tip, I could’ve missed some major iOS wrapper changes…

Thanks

Does this only happen with a certain orientation? I have a similar class that shows a Music Picker on iOS. The music picker will only display in portrait but I’m pretty sure it used to pop-up from an app in either portrait or landscape mode but now it will crash the app if its in landscape. I haven’t had time to fully investigate though.

Indeed, my app orientation is usually set to landscape only… if I allow portrait and use the image picker in portrait orientation it works. In landscape, it hangs.

And I’ve used the github code, to clarify.

I think this may have happened around this commit although I haven’t had a chance to check it and I can’t see anything obvious that would affect the landscape showing of view controllers. You could try rolling back to before this?

Hmm, I just overwrite my JUCE directory with the latest version every now and then, without the git history… It’s inside a folder that is git-controlled, but I could only roll back to 2.0.21 which is three months ago or so. So, not much help there, sorry.

what the…, juce is on git now?

juce is on github? is what I meant to say.

Hey, any news on this one? :slight_smile: