Problems about accessing iPhone photoes(solved!)

Hi all! I know there is a nice tool "enhancement pack
" that can do this, but I really want to make it out myself.

Now I managed to use UIImagePickerController to pick a photo from iPhone, and use a UIImage* pointer pointing it.Then I set up the extern “C” function and let Unity plugin it.
I want my unity script can get the photo, but here is my problem: how can I convert a UIImage into a Texture2D? In other words, how can I pass the pointer from Objective-C to C#? I’m confused.

I have tried several ways, but always got the “SIGBUS” error.

Anyone can help me?

uiimages will not work as textures at all just like that, as they are nowhere near meeting the requirements to be used as textures (pow 2 side lengths, <= 1024x1024, …)

as for the actual transfer itself: send their byte[ ] data over and use them to generate the texture in unity

yep! That’s what i want to know: how to send their byte[ ] data? By using UIImagePNGRepresentation to convert to NSData? And then? I’m new to Objective-C.
I know there is a loadImage function in Texture2D which can load a byte[ ] type data. I tried but failed, I think I’m close to success.

And thank you for your quick reply!

I’m sorry, have to pass that one.
I invested into bliprobs kit, just because no matter how fast I am, it will in any case take far less money (as I would finish it nowhere near 4 hours) to just buy it

Oh… I have studied this for a week, I dont want to give it up like this…LoL

Anyone knows how to send byte[ ] data to Texture2D in Unity script?
Help me plz

I’m sorry I was only half right.

You will have to take the data and fill a Color[ ] array with it and then use SetPixels

You can get the pointer to the byte array in Objective C with

NSData *imageData = UIImagePNGRepresentation(myUIImage);
Byte *byteArray = [imageData bytes];

That will give you a pointer to the byte array. In Unity you can load a byte array to a texture using

Texture2D newTexture = Texture2D.LoadImage(byteArray);

As for getting the byte array over from Objective C to Unity, I don’t have iPhone Advanced myself so it’s not something I’ve done. I imagine you would write a C function in XCode that returns Byte* or void* to access it.

Thanks all above! Let me have a try and tell the results later.

If your byte array is in PNG format then you can use Texture2D.LoadImage to pull it in, e.g. I use this to pull in a 64x64 avatar image

Texture2D img = new Texture2D(64, 64, TextureFormat.RGB24, false);
img.LoadImage(<your byte array>);

I must admit, rather than passing the byte array back from an objective C plugin I use bliprob’s approach of resizing appropriately in objective C, stashing a PNG on the file system and passing back a flag for Unity to then load the image in from file.

Not quite as sexy but works well enough!

Not familiar with operating iPhone file system. Could you tell me how to stashing a PNG and load it in for Unity? What‘s the path?

the loading from Unity is a matter of a WWW call with the file:// protocol and then using the texture handle you get in there.

I have tried the idea for a whole day only to get the “SIGSEGV” signal during runtime, here is the stacktrace:
at (wrapper managed-to-native) ImagePicker.GetImageByPicker () <0xffffffff>
at ImagePicker.GetImageByPicker () <0x0004c>
at ImagePicker.FixedUpdate () <0x00083>
at (wrapper runtime-invoke) System.Object.runtime_invoke_void__this
_ (object,intptr,intptr,intptr) <0xffffffff>
Program received signal: “SIGABRT”.
warning: unrecognized length (0x0) for sigtramp context

I have tried a lot types to pass the data but always get the runtime error. Here is my current code(by passing string to C#, failed again):

Now I have get the UIImage* pointing to the photo.
Here is C# code in Unity:

		[DllImport ("__Internal")]
	private static extern string _GetImageByPicker ();
	public string GetImageByPicker()
	{
		if (Application.platform != RuntimePlatform.OSXEditor)
		{
			thisText.text = "call GetImage";
			return _GetImageByPicker(); 
		}
		return null;
	}
	public Texture2D pickedTex;
	public string str;
	public GUIText thisText;
	public byte[] data1;
	void Start()
	{
		thisText = guiText;
		pickedTex = new Texture2D(480,320);
	}

	void FixedUpdate () {

		if (iPhoneInput.touchCount > 0  iPhoneInput.GetTouch(0).phase == iPhoneTouchPhase.Began)
		{
			str = GetImageByPicker();
			
			if(str!=null)
			{
				data1 = System.Text.Encoding.Unicode.GetBytes(str);
				pickedTex.LoadImage(data1);

				renderer.material.mainTexture = pickedTex;
			}

		}

		
	}

}

And the Objective-C code :

char* ImageToByte (UIImage *image)
{
	if (image == NULL)
		return NULL;
	NSData *data = UIImagePNGRepresentation(image);
	const char* string = [(NSString*)[data bytes] UTF8String];
	//const char* utfstring = [string UTF8String];
	char* res = (char*)malloc(strlen(string) + 1);
	strcpy(res, string);
	return res;
}

extern "C" {
	
	const void  _CallImagePicker ()
	{
		[(AppController*)[UIApplication sharedApplication].delegate callImagePicker];
	}
	
	const char* _GetImageByPicker ()
	{
		UIImage *img;

		img = [(AppController*)[UIApplication sharedApplication].delegate getImage];
		
		return ImageToByte(img);
	}
}

Any mistake I have made? I’m getting crazy…

I have tried passing Byte* , or byte[ ] and fixed all the errors I met, but only get the same signal in the end.
I’m upset… LoL

to dreamora: Thank you for so many explains. Maybe I should try the other way later.

UnmanagedType.ByValTStr is, as the name implies, for string data.
You might want to send it as UnmanagedType.LPArray

See UnmanagedType Enum (System.Runtime.InteropServices) | Microsoft Learn for the related sizeconst handling to get the actual amount of data to read.

Or alternatively write the image to the storage and read it through WWW + file:// protocol again.

I just comment that line, and my current code does pass string data to Unity. I convert the Byte data to UTF8String type which is the same as string in C#.
And then convert back to byte[ ] in C# using
System.Text.Encoding.Unicode.GetBytes(str);

But I failed again…LoL

still not solved. I have post my code, any help would be appreciated!

Finally! I work it out in the way you guys have mentioned! Thank you so much! It works perfect!

would you mind sharing how you finally managed to do it.

I am trying to do the same thing…

I am very interesting your product “Unity iPhone Enhancement”.
I saw some introduction on your website, but have some questions…

1.Would you tell me how do I get your product.
2.The source code is mean objective-c or c or c++ native code???