I want to upload an image jpg to my server. I have try but it didn't work.
I don't what cause the upload failed.
Below the detail code.
Unity C#
public void TakePicture(int maxSize)
{
if (NativeCamera.IsCameraBusy())
{
Debug.Log("Camera Busy");
return;
}
else
{
NativeCamera.Permission permission = NativeCamera.TakePicture((path) =>
{
Debug.Log("Image path: " + path);
if (path != null)
{
// Create a Texture2D from the captured image
Texture2D texture = NativeCamera.LoadImageAtPath(path, maxSize);
//snap.SetPixels(tex.GetPixels());
byte[] bytes = File.ReadAllBytes(path);
Debug.Log("Bytes:" + bytes);
Destroy(texture);
StartCoroutine(upload_ocr_image(bytes));
if (texture == null)
{
Debug.Log("Couldn't load texture from " + path);
return;
}
// Assign texture to a temporary quad and destroy it after 5 seconds
GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 2.5f;
quad.transform.forward = Camera.main.transform.forward;
quad.transform.localScale = new Vector3(1f, texture.height / (float)texture.width, 1f);
Material material = quad.GetComponent<Renderer>().material;
if (!material.shader.isSupported) // happens when Standard shader is not included in the build
material.shader = Shader.Find("Legacy Shaders/Diffuse");
material.mainTexture = texture;
Destroy(quad, 5f);
// If a procedural texture is not destroyed manually,
// it will only be freed after a scene change
Destroy(texture, 5f);
}
}, maxSize);
Debug.Log("Permission result: " + permission);
}
}
IEnumerator upload_ocr_image(byte[] bytes)
{
// UtilityScript.GetComponent<utility>().Sand_Clock_Loading(true);
// yield return new WaitForSeconds(2.5f);
WWWForm formDate = new WWWForm();
formDate.AddField("frameCount", Time.frameCount.ToString());
formDate.AddBinaryData("ocr_image", bytes, "ocr.jpg", "image/jpg");
formDate.AddField("phone_code", "+61");
formDate.AddField("phone_number", "434599859");
using (UnityWebRequest www = UnityWebRequest.Post(web_url.url_upload_ocr_image, formDate))
{
yield return www.Send();
//UtilityScript.GetComponent<utility>().Sand_Clock_Loading(false);
if (www.isNetworkError)
{
Debug.Log(www.error);
// UtilityScript.GetComponent<utility>().MessageBox_Check_Connection();
}
else
{
Debug.Log(www.downloadHandler.text);
}
}
}
And this the code in server codeigniter php.
function upload_ocr_image()
{
$phone_code = $this->input->post('phone_code', true);
$phone_number = $this->input->post('phone_number', true);
$allowedType = array(IMAGETYPE_GIF,IMAGETYPE_JPEG,IMAGETYPE_PNG);
$imgType = exif_imagetype($_FILES['ocr_image']['tmp_name']);
if(!in_array($imgType,$allowedType))
{
echo "Images Type Error. Images Type Only : GIF , JPEG, PNG";
exit;
}
else
{
//upload original size front end slider
$config['upload_path'] = './assets/ocr_image/';
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['file_name'] = $phone_code.$phone_number;
$config['overwrite'] = FALSE;
$config['max_size'] = '8096';
$config['max_width'] = '6000';
$config['max_height'] = '6000';
$this->load->library('upload', $config);
if(!$this->upload->do_upload("ocr_image"))
{
echo "Maximum File Size Only 2 Mb Or Max Width = 2000 , Height = 2000";
exit;
}
else
{
$img_data = $this->upload->data();
// Create Thumbnail
/*
$magicianObj = new imageLib("assets/ocr_image/".$img_data["file_name"].$phone_code.$phone_number);
$magicianObj -> resizeImage(80, 80, 0, true);
$magicianObj -> saveImage("assets/admin/img/photos/".$img_data["raw_name"]."_thumb".$img_data["file_ext"], 100);
$next_id = $next_id.$img_data["file_ext"];
$thumb_name = $img_data["raw_name"]."_thumb".$img_data["file_ext"];
$data = array("photo_name"=>$next_id,
"thumb_photo_name"=>$thumb_name,
"create_date"=>date("Y-m-d H:i:s"));
$this->db->insert("gallery_tbl",$data);
*/
}
}
}
No error found. But it always failed.
This line of code in codeigniter PHP :
if(!$this->upload->do_upload("ocr_image"))
Always return true.
How it work ?, How to upload the picture with proper way ?
Edited :
I use an asset native camera android and ios from unity to take a picture from camera.
Thank You
simply add initialize $this->upload->initialize($config); after
$this->load->library('upload', $config); and check, also check upload directory path is right ? and directory permission
Finally i found the problem.
Just set allowed type extension to except all extension in codeigniter upload file.
change :
$config['allowed_types'] = 'gif|jpg|png|jpeg';
to
$config['allowed_types'] = '*';
Related
I made a script to download some images from the web on click page, and when I moved to the second page, a second set of images was downloaded, but the problem is that the image size is relatively large, and when there are more than one image, it consumes a lot of RAM, how can I save as much memory as possible by compressing the texture
this is my Code
IEnumerator D_Image(string url_)
{
Destroy(Icon.texture);
Icon.texture = LoadT;
using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url_))
{
yield return uwr.SendWebRequest();
if (uwr.result != UnityWebRequest.Result.Success)
{
Icon.texture = ErrorT;
}
else
{
Icon.texture = DownloadHandlerTexture.GetContent(uwr);
}
uwr.Dispose();
}
}
Try compressing the images, it makes a big difference
You can use this code
I found it in this TextureOps add-on
public static Texture2D Scale( Texture sourceTex, int targetWidth, int targetHeight, TextureFormat format = TextureFormat.RGBA32, Options options = new Options() )
{
if( sourceTex == null )
throw new ArgumentException( "Parameter 'sourceTex' is null!" );
Texture2D result = null;
RenderTexture rt = RenderTexture.GetTemporary( targetWidth, targetHeight );
RenderTexture activeRT = RenderTexture.active;
try
{
Graphics.Blit( sourceTex, rt );
RenderTexture.active = rt;
result = new Texture2D( targetWidth, targetHeight, format, options.generateMipmaps, options.linearColorSpace );
result.ReadPixels( new Rect( 0, 0, targetWidth, targetHeight ), 0, 0, false );
result.Apply( options.generateMipmaps, options.markNonReadable );
}
catch( Exception e )
{
Debug.LogException( e );
Object.Destroy( result );
result = null;
}
finally
{
RenderTexture.active = activeRT;
RenderTexture.ReleaseTemporary( rt );
}
return result;
}
Using ARCore for Unity, trying to save Frame.CameraImage.AcquireCameraImageBytes() as image and scanning the image for QR code. But the converted image is not in actual scale and it is repeating, so not able to deduct the QR code correctly.
Here is my code
void Update()
{
using (var image = Frame.CameraImage.AcquireCameraImageBytes())
{
if (image.IsAvailable)
{
byte[] m_EdgeImage = null;
Color32[] pixels = null;
IParser Parser = new ZXingParser();
if (_texture == null || m_EdgeImage == null || _texture.width != image.Width || _texture.height != image.Height)
{
_texture = new Texture2D(image.Width, image.Height, TextureFormat.RGBA32, false, false);
m_EdgeImage = new byte[image.Width * image.Height*4];
}
System.Runtime.InteropServices.Marshal.Copy(image.Y, m_EdgeImage, 0, image.Width * image.Height);
_texture.LoadRawTextureData(m_EdgeImage);
_texture.Apply();
ParserResult Result = Parser.Decode(pixels, _texture.width, _texture.height);
if (Result != null)
{
Debug.Log("QRCODE");
}
else
{
var encodedJpg = _texture.EncodeToJPG();
var path = Application.persistentDataPath;
File.WriteAllBytes(path + "/test.jpg", encodedJpg);
Debug.Log("NOQRCODE");
Application.Quit();
}
}
}
}
Here is the converted image
What is wrong here
An ARCore camera image with its data accessible from the CPU in YUV-420-888 formatCheck this. The buffer size is width*height*1.5 for YUV. You may need to convert YUV to RGB format.
As the title, i want to use locate three Position Pattern.
Example
I want to know how to get the x y position of those pattern when I got a new QR code from a webcamtexture.
How should I implement this is Unity(C#)?
Use the following code for decoding ZXing dll.
private WebCamTexture camTexture;
private Rect screenRect;
void Start()
{
screenRect = new Rect(0, 0, Screen.width, Screen.height);
camTexture = new WebCamTexture();
camTexture.requestedHeight = Screen.height;
camTexture.requestedWidth = Screen.width;
if (camTexture != null)
{
camTexture.Play();
}
}
void OnGUI()
{
// drawing the camera on screen
GUI.DrawTexture(screenRect, camTexture, ScaleMode.ScaleToFit);
// do the reading — you might want to attempt to read less often than you draw on the screen for performance sake
try
{
IBarcodeReader barcodeReader = new BarcodeReader();
// decode the current frame
var result = barcodeReader.Decode(camTexture.GetPixels32(), camTexture.width, camTexture.height);
if (result != null)
{
Debug.Log("DECODED TEXT FROM QR: " +result.Text);
}
ResultPoint[] point = result.ResultPoints;
Debug.Log("X: " + point[0].X + " Y: " + point[1].Y);
}
catch (Exception ex) { Debug.LogWarning(ex.Message); }
}
I had taken reference from ZXing dll link. It also has qr code generator in readme. Go through readme. Its almost same just ResultPoint[] point = result.ResultPoints; has been added to it. This gives the position of the 3 corners of image. Obviously you will need to add the ZXing.dll in plugins folder in the Assets.
Hope this helps to get the result.
This is the hierarchy of Button component.
Button
Image
Text
The script used for rendering is as follows:
for(int ii = 0; ii < idlist.Count; ii++){
GameObject addTypeButton = (GameObject)Instantiate(prefabButton);
addTypeButton.transform.SetParent(ParentPanel, false);
var mybutton = addTypeButton.GetComponent<MyButton>();
//set text
mybutton.text.text = (string)sometext[ii];
//get image
WWW www = new WWW((string)someImageUrl[ii]);
yield return www;
//set image
var b64_bytes = System.Convert.FromBase64String(www.text);
Texture2D tex = new Texture2D(1, 1, TextureFormat.RGB24, false);
tex.EncodeToPNG();
tex.LoadImage(b64_bytes);
//yield return new WaitForSeconds (5) ;
mybutton.image.material.mainTexture = tex;
//testing
File.WriteAllBytes(Application.dataPath + "/../Saved["+ii +"].png", b64_bytes);
}
Testing command generates proper images in the sequence.
However, in Unity the image is rendered on the next object.
Here's the Screenshot
Where exactly I am going wrong?
Don not use WWW.text to load images. This is what WWW.bytes is there for. So, your System.Convert.FromBase64String(www.text); should be removed. You also don't need the Texture2D.EncodeToPNG(); function here since the image you are downloading is already in png or jpeg format. Just save the downloaded image bytes directly.
Finally, if you want your saving stuff to work on every platform, you have to use Application.persistentDataPath instead of Application.dataPath. You should also use Path.Combine to concatenate paths instead of doing it manually.
for (int ii = 0; ii < idlist.Count; ii++)
{
GameObject addTypeButton = (GameObject)Instantiate(prefabButton);
addTypeButton.transform.SetParent(ParentPanel, false);
var mybutton = addTypeButton.GetComponent<MyButton>();
//set text
mybutton.text.text = (string)sometext[ii];
//get image
WWW www = new WWW((string)someImageUrl[ii]);
yield return www;
//set image
byte[] downloadedImage = www.bytes;
Texture2D tex = new Texture2D(1, 1, TextureFormat.RGB24, false);
tex.LoadImage(downloadedImage);
//yield return new WaitForSeconds (5) ;
mybutton.image.material.mainTexture = tex;
//testing
string savePath = Application.persistentDataPath;
savePath = Path.Combine(savePath, "images");
savePath = Path.Combine(savePath, ii.ToString());
savePath = Path.Combine(savePath, ".png");
File.WriteAllBytes(savePath, downloadedImage);
}
I'm new in Unity and I'm trying to save an image for get it after. I try Application.CaptureScreenshot and the method with Texture2D.ReadPixel, i try to save in persistentDataPath (/data/user/0/my.package.name/files/), in /sdcard/Download/ and in /storage/emulated/0/Download. No method worked. In every manifest of my project I have WRITE_EXTERNAL_STORAGE permission. If I save to persistent data, I don't found it I found only cache of UnityAds, and if I save to Download folder I get access denied.
Anyone can help me?
Here's my code :
IEnumerator ScreenShot(){
yield return new WaitForEndOfFrame ();
Application.CaptureScreenshot ("ball.png");
Application.CaptureScreenshot ("/sdcard/Download/ball.png");
int width = Screen.width;
int height = Screen.height;
Texture2D tex = new Texture2D (width, height, TextureFormat.RGB24, false);
tex.ReadPixels (new Rect (0, 0, width, height), 0, 0);
tex.Apply ();
byte[] bytes = tex.EncodeToJPG ();
File.WriteAllBytes ("sdcard/Download/ball.png", bytes);
File.WriteAllBytes (Application.persistentDataPath + "/ball.png", bytes);
}
Before i check if folders exist :
if(!System.IO.Directory.Exists("/sdcard/Download/"))
{
System.IO.Directory.CreateDirectory ("/sdcard/Download/");
}
if(!System.IO.Directory.Exists(Application.persistentDataPath))
{
System.IO.Directory.CreateDirectory (Application.persistentDataPath);
}
And I start IEnumerator with:
StartCoroutine(ScreenShot());
What I'm doing wrong?
Here is what works for me:
string destination = DateTime.Now.ToString ("yyyy-MM-dd-HHmmss") + ".png";
string fullDestination = Path.Combine (Application.persistentDataPath, destination);
Application.CaptureScreenshot (destination);
SharingWriter.WriteTextInstant ("Preparing...");
FileInfo fileInfo = new FileInfo(fullDestination);
while(fileInfo == null || fileInfo.Exists == false)
{
yield return null;
fileInfo = new FileInfo(fullDestination);
}
Application.CaptureScreenshot handles everything, no need to worry about reading pixels and writing to files that's redundant. Just have a while loop afterwards in the Coroutine to wait for the magic to happen! I used this to create screenshot sharing functionality for mobile.