分类 Unity 下的文章

using UnityEngine;
using System.Collections;
using OpenCvSharp;
 
public class VideoTest : MonoBehaviour
{
    public WebCamTexture cameraTexture;
    Texture2D rt;
    public string cameraName = "";
    private bool isPlay = false;
    static int mPreviewWidth = 320;
    static int mPreviewHeight = 240;
    bool state = false;
    CascadeClassifier haarCascade;
    WebCamDevice[] devices;
    // Use this for initialization
    void Start()
    {
        rt = new Texture2D(mPreviewWidth, mPreviewHeight, TextureFormat.RGB565, false);
        temp = new Texture2D(mPreviewWidth, mPreviewHeight, TextureFormat.RGB565, false);
        StartCoroutine(Test());
        haarCascade = new CascadeClassifier(Application.streamingAssetsPath + "/haarcascades/haarcascade_frontalface_alt2.xml");
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
 
    IEnumerator Test()
    {
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            devices = WebCamTexture.devices;
            cameraName = devices[0].name;
            cameraTexture = new WebCamTexture(cameraName, mPreviewWidth, mPreviewHeight, 15);
            cameraTexture.Play();
            isPlay = true;
        }
    }
    Mat haarResult;
    byte[] bs;
    void OnGUI()
    {
        if (isPlay)
        {
            GUI.DrawTexture(new UnityEngine.Rect(0, 0, mPreviewWidth, mPreviewHeight), cameraTexture, ScaleMode.ScaleToFit);
 
            if (GUI.Button(new UnityEngine.Rect(0, 240, 80, 80), "START"))
            {
                if (state)
                {
                    state = false;
                    return;
                }
                else
                {
                    state = true;
                }
            }
 
            if (state)
            {
                // Detect faces
                haarResult = DetectFace(haarCascade, GetTexture2D(cameraTexture));
                bs = haarResult.ToBytes(".png");
                rt.LoadImage(bs);
                rt.Apply();
                GUI.DrawTexture(new UnityEngine.Rect(mPreviewWidth, 0, mPreviewWidth, mPreviewHeight), rt, ScaleMode.StretchToFill);
            }
 
        }
 
    }
 
    Mat result;
    OpenCvSharp.Rect[] faces;
    Mat src;
    Mat gray = new Mat();
    Size axes = new Size();
    Point center = new Point();
    /// <summary>
    /// 
    /// </summary>
    /// <param name="cascade"></param>
    /// <returns></returns>
    private Mat DetectFace(CascadeClassifier cascade, Texture2D t)
    {
        src = Mat.FromImageData(t.EncodeToPNG(), ImreadModes.Color);
        result = src.Clone();
        Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
        src = null;
        // Detect faces
        faces = cascade.DetectMultiScale(gray, 1.08, 2, HaarDetectionType.ScaleImage, new Size(30, 30));
 
        // Render all detected faces
        for (int i = 0; i < faces.Length; i++)
        {
            center.X = (int)(faces[i].X + faces[i].Width * 0.5);
            center.Y = (int)(faces[i].Y + faces[i].Height * 0.5);
            axes.Width = (int)(faces[i].Width * 0.5);
            axes.Height = (int)(faces[i].Height * 0.5);
            Cv2.Ellipse(result, center, axes, 0, 0, 360, new Scalar(255, 0, 255), 4);
        }
        return result;
    }
    Texture2D temp;
    Texture2D GetTexture2D(WebCamTexture wct)
    {
        temp.SetPixels(wct.GetPixels());
        temp.Apply();
        return temp;
    }
}

OpenCvSharp github地址 https://github.com/shimat/opencvsharp

工程下载(.3.5f1&win10x64)http://pan.baidu.com/s/1pLy6W4N

OpenCV相关插件下载 https://pan.baidu.com/s/1c2agKHM

000033xpfpfgp4asaaf6ba.jpg

package com.xuefei.game;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import com.unity3d.player.UnityPlayerNativeActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
 
public class MainActivity extends UnityPlayerNativeActivity {
    public static Context context;
    public static MainActivity mainActivity;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        mainActivity = this;
    }
 
    // 保存到相册
    public static void savePng(final String fileName) {
 
        context = mainActivity.getApplicationContext();
 
        mainActivity.runOnUiThread(new Runnable() {
            public void run() {
 
                Bitmap bitmap = BitmapFactory.decodeFile(Environment
                        .getExternalStorageDirectory()
                        + "/Android/data/com.xuefei.game/files/"
                        + fileName
                        + ".png");
 
                File file = new File(Environment.getExternalStorageDirectory()
                        + "/DCIM/Camera", fileName + ".jpg");
 
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(file);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    Log.w("cat", e.toString());
                }
                bitmap.compress(CompressFormat.JPEG, 100, fos);
 
                try {
                    fos.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    Log.w("cat", e.toString());
                }
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    Log.w("cat", e.toString());
                }
                bitmap.recycle();//扫描保存的图片
                context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" +Environment.getExternalStorageDirectory()
                        + "/DCIM/Camera/"+fileName + ".jpg")));
                 
                Toast.makeText(context, "照片已保存到相册", Toast.LENGTH_SHORT).show();
  
            }
        });
    }
}

Unity中代码:

        if (GUI.Button(new Rect(0, 720, 400, 120), "SavePng"))
        {
            StartCoroutine(SavePngToSD(DateTime.Now.ToFileTime().ToString()));
        }
 
    /// <summary>
    /// 截图后先检测图片是否保存成功然后调用保存到相册
    /// </summary>
    /// <param name="name"></param>
    public void SavePng(string name)
    {
#if UNITY_ANDROID
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.CallStatic("SavePng", name);
#elif  UNITY_IPHONE
 
#endif
    }
 
/// <summary>
    /// 保存截图到相册
    /// </summary>
    /// <param name="pngName"></param>
    /// <returns></returns>
    IEnumerator SavePngToSD(string pngName)
    {
        yield return new WaitForEndOfFrame();
        Application.CaptureScreenshot(pngName + ".png");
        while (!IsFileExistByPath(Application.persistentDataPath + "/" + pngName + ".png"))
        {
            yield return new WaitForSeconds(0.05f);
        }
        SavePng(pngName);
        yield return new WaitForSeconds(0.3f);
        //测试请求文件
        WWW www = new WWW("file:///" + Application.persistentDataPath + "/" + pngName + ".png");
 
        yield return www;
    }
 
    /// <summary>
    /// 检测文件是否存在
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static bool IsFileExistByPath(string path)
    {
        FileInfo info = new FileInfo(path);
        bool b = false;
        if (info == null || info.Exists == false)
        {
            b = false;
        }
        else
        {
            b = true;
        }
        return b;
    }

注意文件路径是否存在,不存在就创建

流程:Unity截屏--调用安卓拷贝到相册--扫描保存的文件

解决的问题:截屏图片在相册不显示。

1.png
2.png

using UnityEngine;
using System.Collections;
using Id3Lib;
using NAudio.Wave;
using System.IO;
using System;
using System.Text;
using System.Runtime.InteropServices;
public class MusicPlayer : MonoBehaviour
{ 
 
    private IWavePlayer iwavePlayer;
    private WaveStream waveStream;
    private WaveChannel32 waveChannel32;
    Texture2D t;
    string path=""; 
    // Use this for initialization
    void Start()
    {
        
    }
 
    void LoadMusic(string path)
    { 
        byte[] imageData;
        using (FileStream fsRead = new FileStream(path, FileMode.Open))
        {
            int fsLen = (int)fsRead.Length;
            imageData = new byte[fsLen];
            fsRead.Read(imageData, 0, imageData.Length);
        }
        LoadAudioFromData(imageData);
        t = GetAlbumCover(path);
    }
 
    private bool LoadAudioFromData(byte[] data)
    {
        try
        {
            MemoryStream tmpStr = new MemoryStream(data);
            waveStream = new Mp3FileReader(tmpStr); 
            waveChannel32 = new WaveChannel32(waveStream);
 
            iwavePlayer = new WaveOut();
            iwavePlayer.Init(waveChannel32);
            return true;
        }
        catch (System.Exception ex)
        {
            Debug.LogWarning("Error! " + ex.Message);
        }
        return false;
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
 
 
    void OnGUI()
    {
        if (GUI.Button(new Rect(0, 0, 120, 30), "选择音乐"))
        {
            OpenFileName ofn = new OpenFileName();
 
            ofn.structSize = Marshal.SizeOf(ofn);
              
            ofn.filter = "mp3(*.mp3)\0*.mp3";
 
            ofn.file = new string(new char[256]);
 
            ofn.maxFile = ofn.file.Length;
 
            ofn.fileTitle = new string(new char[64]);
 
            ofn.maxFileTitle = ofn.fileTitle.Length;
 
            ofn.initialDir = UnityEngine.Application.dataPath;//默认路径  
 
            ofn.title = "选择音乐";
 
            ofn.defExt = "mp3";//显示文件的类型  
            //注意 一下项目不一定要全选 但是0x00000008项不要缺少  
            ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;//OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR  
 
            if (WindowDll.GetOpenFileName(ofn))
            {
                Debug.Log("Selected file with full path: {0}" + ofn.file);
                LoadMusic(ofn.file);
                path = ofn.file;
            }
            ofn = null;
            Resources.UnloadUnusedAssets();
        }
        if(GUI.Button(new Rect(0,30,120,30),"播放"))
        {
            iwavePlayer.Play();
        }
        if (GUI.Button(new Rect(0, 60, 120, 30), "暂停"))
        {
            iwavePlayer.Pause();
        }
        if (GUI.Button(new Rect(0, 90, 120, 30), "停止"))
        {
            iwavePlayer.Stop(); 
        }
        GUI.Label(new Rect(200, 170, 500, 30), path);
        if(t!=null)
        {
            GUI.DrawTexture(new Rect(200, 200, 200, 200), t);
        }
    }
 
    void OnApplicationQuit()
    {
        if (iwavePlayer!=null)
        {
            iwavePlayer.Dispose();
        }
    }
    /// <summary>
    /// 获取音乐封面
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public Texture2D GetAlbumCover(string path)
    {
        Texture2D image = null;
        FileStream fs = new FileStream(path, FileMode.Open);
        try
        {
            byte[] header = new byte[10]; //标签头
            int offset = 0;
            bool haveAPIC = false;
            fs.Read(header, 0, 10);
            offset += 10;
            string head = Encoding.Default.GetString(header, 0, 3);
 
            if (head.Equals("ID3"))
            {
                int sizeAll = header[6] * 0x200000 //获取该标签的尺寸,不包括标签头
                + header[7] * 0x4000
                + header[8] * 0x80
                + header[9];
                int size = 0;
                byte[] body = new byte[10]; //数据帧头,这里认为数据帧头不包括编码方式
                fs.Read(body, 0, 10);
                offset += 10;
                head = Encoding.Default.GetString(body, 0, 4);
                while (offset < sizeAll) //当数据帧不是图片的时候继续查找
                {
                    if (("APIC".Equals(head))) { haveAPIC = true; break; }
                    size = body[size + 4] * 0x1000000 //获取该数据帧的尺寸(不包括帧头)
                    + body[size + 5] * 0x10000
                    + body[size + 6] * 0x100
                    + body[size + 7];
                    body = new byte[size + 10];
                    fs.Read(body, 0, size + 10);
                    offset += size + 10;
                    head = Encoding.Default.GetString(body, size, 4);
                }
                if (haveAPIC)
                {
                    size = body[size + 4] * 0x1000000
                    + body[size + 5] * 0x10000
                    + body[size + 6] * 0x100
                    + body[size + 7];
                    byte[] temp = new byte[9];
                    byte[] temptype = new byte[10];
                    fs.Seek(1, SeekOrigin.Current);
                    fs.Read(temp, 0, 9);
                    int i = 0;
                    switch (Encoding.Default.GetString(temp))
                    {
                        case "image/jpe":
 
                            while (i < size) //jpeg开头0xFFD8
                            {
                                if (temptype[0] == 0 && temptype[1] == 255 && temptype[2] == 216)
                                {
                                    break;
                                }
                                fs.Seek(-2, SeekOrigin.Current);
                                fs.Read(temptype, 0, 3);
                                i++;
                            }
                            fs.Seek(-2, SeekOrigin.Current);
                            break;
                        case "image/jpg":
 
                            while (i < size) //jpg开头0xFFD8
                            {
                                if (temptype[0] == 0 && temptype[1] == 255 && temptype[2] == 216)
                                {
                                    break;
                                }
                                fs.Seek(-2, SeekOrigin.Current);
                                fs.Read(temptype, 0, 3);
                                i++;
                            }
                            fs.Seek(-2, SeekOrigin.Current);
                            break;
                        case "image/gif":
 
                            while (i < size) //gif开头474946
                            {
                                if (temptype[0] == 71 && temptype[1] == 73 && temptype[2] == 70)
                                {
                                    break;
                                }
                                fs.Seek(-2, SeekOrigin.Current);
                                fs.Read(temptype, 0, 3);
                                i++;
                            }
                            fs.Seek(-3, SeekOrigin.Current);
                            break;
                        case "image/bmp":
 
                            while (i < size) //bmp开头424d
                            {
                                if (temptype[0] == 66 && temptype[1] == 77)
                                {
                                    break;
                                }
                                fs.Seek(-1, SeekOrigin.Current);
                                fs.Read(temptype, 0, 2);
                                i++;
                            }
                            fs.Seek(-2, SeekOrigin.Current);
                            break;
                        case "image/png":
                            while (i < size) //png开头89 50 4e 47 0d 0a 1a 0a
                            {
                                if (temptype[0] == 137 && temptype[1] == 80 && temptype[2] == 78 && temptype[3] == 71 && temptype[4] == 13)
                                {
                                    break;
                                }
                                fs.Seek(-9, SeekOrigin.Current);
                                fs.Read(temptype, 0, 10);
                                i++;
                            }
                            fs.Seek(-10, SeekOrigin.Current);
                            break;
                        default://FFFB为音频的开头
                            break;
                    }
 
                    byte[] imageBytes = new byte[size];
                    fs.Read(imageBytes, 0, size);
                    image = new Texture2D(128, 128);
                    image.LoadImage(imageBytes);
                }
                else
                {
                    image = null;
                }
            }
            else
            {
                image = null;
            }
        }
        catch (Exception ex)
        {
            Debug.LogWarning(ex.Message);
        }
        finally
        {
            fs.Close();
        }
        return image;
    }
}

20160218152426016.png

点击这里下载项目文件