using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Networking; using System.Text.RegularExpressions; using System.Data.SqlClient; using TMPro; using System; using System.IO; using System.Text; using ZXing; using ZXing.QrCode; using System.Net; using SimpleJSON; using System.ComponentModel; using System.Runtime.InteropServices; using ExifLib; using static NativeCamera; using System.Linq; public class 錄音測試 : MonoBehaviour { [SerializeField] RawImage 拍照用; [SerializeField] TextMeshProUGUI 失敗1; [SerializeField] TextMeshProUGUI 失敗; // Start is called before the first frame update //[SerializeField] GameObject 照片欄, 照片欄1, 照片欄2, 照片欄3, 照片欄4,文字欄; //[SerializeField] RawImage 縮圖, 縮圖1, 縮圖2, 縮圖3, 縮圖4; //private Texture2D 上傳圖, 上傳圖1, 上傳圖2, 上傳圖3, 上傳圖4; //[SerializeField] GameObject 照片欄刪除, 照片欄刪除1, 照片欄刪除2, 照片欄刪除3, 照片欄刪除4; //[SerializeField] GameObject 照片欄新增, 照片欄新增1, 照片欄新增2, 照片欄新增3, 照片欄新增4; [SerializeField] GameObject 拍頁; [SerializeField] GameObject 主頁; [SerializeField] GameObject 返回紐; [SerializeField] GameObject 文字欄; [SerializeField] GameObject[] 照片欄Array; Texture2D[] 上傳圖Array = new Texture2D[5]; [SerializeField] RawImage[] 縮圖Array; [SerializeField] GameObject[] 照片欄刪除Array; [SerializeField] GameObject[] 照片欄新增Array; private int 照片欄數量 = 0; private WebCamTexture myCam; [SerializeField] GameObject 錄音頁; [SerializeField] GameObject 錄音頁叉叉; [SerializeField] GameObject 錄音顯示; [SerializeField] GameObject 錄音紐; [SerializeField] Button 錄音開始; [SerializeField] Button 錄音結束; [SerializeField] GameObject 相片選擇頁; private string 地址1, 地址2,錄音流水,控制表單號; string[] 圖片流水 = new string[5]; [SerializeField] TMP_InputField 貼文內容; public CanvasScaler canvasScaler; private AudioClip recordedClip; public AudioSource audioSource; [SerializeField] TextMeshProUGUI 顯示; [SerializeField] TextMeshProUGUI 顯示1; [SerializeField] TextMeshProUGUI 顯示2; public Slider progressBar; [SerializeField] TextMeshProUGUI timeText; public Button playPauseButton; public Sprite playSprite; public Sprite pauseSprite; private float currentTime; private bool isPlaying; private bool isDraggingProgress = false; private float recordingTime = 0f; private bool isRecording = false; private float maxRecordingTime = 180f; public RawImage imageDisplay; private Texture2D 存圖1; public RawImage 圖1; [SerializeField] TMP_InputField 緯度; [SerializeField] TMP_InputField 經度; private int totalPages; [SerializeField] Button 彈跳是; [SerializeField] Button 彈跳否; [SerializeField] Button 彈跳叉; [SerializeField] GameObject 彈跳面板; [SerializeField] TextMeshProUGUI 彈跳文字; [SerializeField] GameObject 讀取面板; [SerializeField] TextMeshProUGUI 讀取; private string loadingText = ""; private int dotCount = 0; private string 圖片資料庫名稱 = ""; private string 錄音資料庫名稱 = ""; bool pic = false; void Start() { Screen.autorotateToPortrait = false; Screen.orientation = ScreenOrientation.Portrait; if (Screen.orientation == ScreenOrientation.LandscapeLeft) { float rate = 900.0f / 1900.0f; if (Main.Global.raterate) { canvasScaler.matchWidthOrHeight = 1f; } else { canvasScaler.matchWidthOrHeight = 0f; } } //SQL_CommString.SQL_連線字串_正式_SQL(); //SQL_CommString.SQL_連線字串_圖片_SQL(); //SQL_CommString.SQL_連線字串_錄音_SQL(); StartCoroutine(AnimateText()); audioSource.Stop(); 主頁.SetActive(true); 拍頁.SetActive(false); 返回紐.SetActive(true); 錄音顯示.SetActive(false); //錄音紐.SetActive(true); 照片欄Array[0].SetActive(true); 照片欄刪除Array[0].SetActive(false); 照片欄新增Array[0].SetActive(true); 文字欄.SetActive(false); for (int i = 1; i < 照片欄Array.Length; i++) { 照片欄Array[i].SetActive(false); 照片欄刪除Array[i].SetActive(false); 照片欄新增Array[i].SetActive(true); } 資料庫選擇(); } private void 資料庫選擇() { SQL_game_sys.SQL_讀取資料庫名稱("音"); if (SQL_Module.dr.Read()) { 錄音資料庫名稱 =SQL_Module.dr["資料庫名稱"].ToString(); SQL_game_sys.SQL_讀取資料庫名稱("圖"); if (SQL_Module.dr.Read()) { 圖片資料庫名稱 =SQL_Module.dr["資料庫名稱"].ToString(); Debug.Log(錄音資料庫名稱); Debug.Log(圖片資料庫名稱); } else { 彈跳面板開啟("圖片資料庫已滿,請找系統管理員!!", false, false, true, () => { }, () => { }, back1); } } else { 彈跳面板開啟("錄音資料庫已滿,請找系統管理員!!", false, false, true, () => { }, () => { }, back1); } } IEnumerator AnimateText() { string qqq = 讀取.text.ToString(); while (true) { yield return new WaitForSeconds(0.5f); if (dotCount < 3) { loadingText += "."; dotCount++; } else { loadingText = ""; dotCount = 0; } 讀取.text = qqq+loadingText; } } public void 照片選擇() { 主頁.SetActive(false); 相片選擇頁.SetActive(true); 返回紐.SetActive(false); } public void 照片欄位新增() { if (照片欄數量 < 照片欄Array.Length) { 照片欄數量++; 照片欄新增Array[照片欄數量 - 1].SetActive(false); 照片欄刪除Array[照片欄數量 - 1].SetActive(true); if (照片欄數量 == 照片欄Array.Length) { 文字欄.SetActive(true); } else { 照片欄Array[照片欄數量].SetActive(true); } 選擇照片(); 相片選擇頁.SetActive(false); } } public void 欄位刪除(int index) { if (照片欄數量==5) { 文字欄.SetActive(false); } else { 照片欄Array[照片欄數量].SetActive(false); } for (int i = index; i < 照片欄數量 - 1; i++) { 縮圖Array[i].texture = 縮圖Array[i + 1].texture; 上傳圖Array[i] = 上傳圖Array[i + 1]; } 照片欄刪除Array[照片欄數量-1].SetActive(false); 照片欄新增Array[照片欄數量-1].SetActive(true); 上傳圖Array[照片欄數量-1]=null; 縮圖Array[照片欄數量-1].texture=null; 照片欄數量--; } public void 選擇照片() { // 調用Native插件的選擇照片函數 NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) => { if (path != null) { // 加載並顯示選擇的照片 StartCoroutine(LoadImage(path)); 主頁.SetActive(true); } else { 照片欄新增Array[照片欄數量 - 1].SetActive(true); 照片欄刪除Array[照片欄數量 - 1].SetActive(false); 照片欄Array[照片欄數量].SetActive(false); 照片欄數量--; 主頁.SetActive(true); } }); // 檢查權限 if (permission == NativeGallery.Permission.Granted) { // 權限已經被授予 Debug.Log("Gallery permission granted"); } else if (permission == NativeGallery.Permission.ShouldAsk) { // 權限尚未被授予,需要詢問用戶 Debug.Log("Gallery permission should ask"); } else { // 權限被拒絕 Debug.Log("Gallery permission denied"); } IEnumerator LoadImage(string path) { UnityWebRequest www = UnityWebRequestTexture.GetTexture("file://" + path); yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError) { Debug.LogError("Failed to load image: " + www.error); } else { Texture2D texture = ((DownloadHandlerTexture)www.downloadHandler).texture; Texture2D texture1 = ((DownloadHandlerTexture)www.downloadHandler).texture; byte[] imageBytes = File.ReadAllBytes(path); try { ExifLib.JpegInfo jpi = ExifLib.ExifReader.ReadJpeg(imageBytes, "Foo"); //Debug.Log("Orientation: " + jpi.Orientation.ToString()); //Debug.Log(jpi.Width); //Debug.Log(jpi.Height); if (jpi.Width >jpi.Height) { texture =ResizeTexture(texture, 1920, 1080); } else { texture =ResizeTexture(texture, 1080, 1920); } texture1=ResizeTexture(texture1, 196, 196); texture =AdjustTextureOrientation(texture, jpi.Orientation); texture1 =AdjustTextureOrientation(texture1, jpi.Orientation); } catch (Exception ex) { Debug.LogError("Error reading Exif data: " + ex.Message); } 上傳圖Array[照片欄數量 - 1] = texture; 縮圖Array[照片欄數量 - 1].texture = texture1; } } Texture2D ResizeTexture(Texture2D originalTexture, int newWidth, int newHeight) { Texture2D resizedTexture = new Texture2D(newWidth, newHeight, originalTexture.format, true); Color[] pixels = new Color[newWidth * newHeight]; float incX = ((float)1 / originalTexture.width) * ((float)originalTexture.width / newWidth); float incY = ((float)1 / originalTexture.height) * ((float)originalTexture.height / newHeight); for (int x = 0; x < newWidth; x++) { for (int y = 0; y < newHeight; y++) { pixels[y * newWidth + x] = originalTexture.GetPixelBilinear(incX * x, incY * y); } } resizedTexture.SetPixels(pixels); resizedTexture.Apply(); return resizedTexture; } Texture2D AdjustTextureOrientation(Texture2D originalTexture, ExifOrientation orientation) { Texture2D adjustedTexture = new Texture2D(originalTexture.width, originalTexture.height); switch (orientation) { case ExifOrientation.TopLeft: // 图片方向为正常方向,无需调整 adjustedTexture = originalTexture; break; case ExifOrientation.TopRight: // 逆时针旋转图片90度 adjustedTexture = RotateTexture(originalTexture, -90f); break; case ExifOrientation.BottomRight: // 旋转180度 adjustedTexture = RotateTexture(originalTexture, 180f); break; case ExifOrientation.BottomLeft: adjustedTexture = RotateTexture(originalTexture, 90f); break; default: // 默认情况下,返回原始图片 adjustedTexture = originalTexture; break; } return adjustedTexture; } Texture2D RotateTexture(Texture2D originalTexture, float angle) { // Calculate the dimensions of the rotated texture int width = originalTexture.width; int height = originalTexture.height; float rotatedWidth = Mathf.Abs(width * Mathf.Cos(angle * Mathf.Deg2Rad)) + Mathf.Abs(height * Mathf.Sin(angle * Mathf.Deg2Rad)); float rotatedHeight = Mathf.Abs(width * Mathf.Sin(angle * Mathf.Deg2Rad)) + Mathf.Abs(height * Mathf.Cos(angle * Mathf.Deg2Rad)); // Create a new texture to store rotated pixels Texture2D rotatedTexture = new Texture2D(Mathf.RoundToInt(rotatedWidth), Mathf.RoundToInt(rotatedHeight)); // Get the pixel data of the original texture Color32[] pixels = originalTexture.GetPixels32(); Color32[] rotatedPixels = new Color32[Mathf.RoundToInt(rotatedWidth) * Mathf.RoundToInt(rotatedHeight)]; // Calculate the center of the original texture float centerX = width / 2f; float centerY = height / 2f; // Iterate over each pixel in the rotated texture for (int x = 0; x < rotatedTexture.width; x++) { for (int y = 0; y < rotatedTexture.height; y++) { // Calculate the coordinates of the pixel in the original texture float originalX = Mathf.Cos(-angle * Mathf.Deg2Rad) * (x - rotatedWidth / 2) - Mathf.Sin(-angle * Mathf.Deg2Rad) * (y - rotatedHeight / 2) + centerX; float originalY = Mathf.Sin(-angle * Mathf.Deg2Rad) * (x - rotatedWidth / 2) + Mathf.Cos(-angle * Mathf.Deg2Rad) * (y - rotatedHeight / 2) + centerY; // Get the pixel color from the original texture and assign it to the rotated texture if (originalX >= 0 && originalX < width && originalY >= 0 && originalY < height) { int index = Mathf.RoundToInt(originalY) * width + Mathf.RoundToInt(originalX); rotatedPixels[y * rotatedTexture.width + x] = pixels[index]; } else { // If the coordinates are outside the bounds of the original texture, set the pixel color to transparent rotatedPixels[y * rotatedTexture.width + x] = new Color32(0, 0, 0, 0); } } } // Set the rotated pixels to the rotated texture and apply changes rotatedTexture.SetPixels32(rotatedPixels); rotatedTexture.Apply(); return rotatedTexture; } } public void 新增錄音() { 錄音頁.SetActive(true); 錄音頁叉叉.SetActive(true); 主頁.SetActive(false); 返回紐.SetActive(false); 錄音開始.interactable = true; 錄音結束.interactable = false; 顯示.text="錄音最大時長為3分鐘,按下start後開始錄音"; 顯示1.text=""; timeText.text="0:00 / 0:00"; } public void 關閉錄音頁() { 錄音頁.SetActive(false); } public void 刪除錄音() { if (recordedClip != null) { // 清除錄音的緩衝區 recordedClip = null; } 顯示.text=""; 顯示1.text=""; timeText.text="0:00 / 0:00"; 錄音顯示.SetActive(false); 錄音紐.SetActive(true); } public void StartRecording() { 錄音頁叉叉.SetActive(false); 錄音開始.interactable = false; 錄音結束.interactable = true; // 開始錄音 if (recordedClip != null) { // 清除錄音的緩衝區 recordedClip = null; } isRecording = true; recordingTime = 0f; recordedClip = Microphone.Start(null, false, 181, 44100); audioSource.clip=null; 顯示.text="錄音中..."; } public void StopRecording() { // 停止錄音 Microphone.End(null); isRecording = false; recordedClip=TrimSilenceFromAudioClip(recordedClip); audioSource.clip=recordedClip; UpdateProgressBar(); UpdateTimeText(); 錄音頁.SetActive(false); 錄音顯示.SetActive(true); 錄音紐.SetActive(false); 主頁.SetActive(true); 返回紐.SetActive(true); } AudioClip TrimSilenceFromAudioClip(AudioClip clip) { // 獲取錄音副本的音頻數據 float[] data = new float[clip.samples * clip.channels]; clip.GetData(data, 0); // 計算錄音的持續時間(以秒為單位) float clipDuration = clip.length; // 計算有聲的部分的持續時間(以秒為單位) float soundDuration = recordingTime+1; // 計算有聲部分的開始和結束索引 int startSample = 0; int endSample = Mathf.FloorToInt((soundDuration / clipDuration) * clip.samples); // 創建新的音頻數據副本,僅包含有聲的部分 int newSamples = endSample - startSample; float[] newData = new float[newSamples]; Array.Copy(data, startSample, newData, 0, newSamples); AudioClip trimmedClip = AudioClip.Create("TrimmedAudio", newSamples, clip.channels, clip.frequency, false); trimmedClip.SetData(newData, 0); return trimmedClip; } public void TogglePlayPause() { // 切換播放/暫停 if (isPlaying) { audioSource.Pause(); playPauseButton.image.sprite = playSprite; isPlaying = false; } else { audioSource.Play(); playPauseButton.image.sprite = pauseSprite; isPlaying = true; } } void Update() { if (isPlaying) { UpdateProgressBar(); UpdateTimeText(); // 如果音頻播放完畢,則停止播放並將播放標誌設置為false if (!audioSource.isPlaying) { playPauseButton.image.sprite = playSprite; isPlaying = false; audioSource.time = 0; progressBar.value = 0; UpdateTimeText(); } } else { if(audioSource.clip != null) { UpdateProgressBar(); UpdateTimeText(); } } if (isRecording) { recordingTime += Time.deltaTime; UpdateRecordingTimeText(); if (recordingTime >= maxRecordingTime) { StopRecording(); } } } void UpdateRecordingTimeText() { 顯示1.text = FormatTime(recordingTime); } void UpdateProgressBar() { // 更新進度條的值 if (recordedClip != null && audioSource.time != recordedClip.length) { progressBar.value = audioSource.time / recordedClip.length; UpdateTimeText(); } } void UpdateTimeText() { // 更新時間文字顯示 if (recordedClip != null) { currentTime = audioSource.time; timeText.text = FormatTime(currentTime) + " / " + FormatTime(recordedClip.length); } } string FormatTime(float time) { // 格式化時間 int minutes = Mathf.FloorToInt(time / 60); int seconds = Mathf.FloorToInt(time % 60); return string.Format("{0:00}:{1:00}", minutes, seconds); } public void OnProgressBarValueChanged() { // 當 Bar 條的值發生變化時(用戶拖動),更新播放器的播放位置 float newTime = progressBar.value * recordedClip.length; if (newTime < 0) { newTime = 0; } else if (newTime > recordedClip.length) { newTime = recordedClip.length; } audioSource.time = newTime; } public void OnPointerDownProgressBar() { // 當用戶按下 Bar 條時,設置拖動標誌為true isDraggingProgress = true; } public void OnPointerUpProgressBar() { // 當用戶放開 Bar 條時,設置拖動標誌為false isDraggingProgress = false; } //public void 上傳() //{ // string connectionString = "Data Source=106.1.48.106,4567;Initial Catalog=OW-ERP-SYS;User ID=B70340;Password=Lee0911274990"; // Debug.Log(connectionString); // using (SqlConnection connection = new SqlConnection(connectionString)) // { // try // { // connection.Open(); // byte[] wavData = WavUtility.FromAudioClip(recordedClip); // string query = "INSERT INTO 測試錄音檔 (名稱, 音檔) VALUES (@流水號, @binary_file)"; // using (SqlCommand command = new SqlCommand(query, connection)) // { // 添加流水號參數 // command.Parameters.AddWithValue("@流水號", "測試"); // 添加二進制圖片數據參數 // command.Parameters.AddWithValue("@binary_file", wavData); // int rowsAffected = command.ExecuteNonQuery(); // Debug.Log("成功插入 " + rowsAffected + " 行數據"); // } // } // catch (Exception ex) // { // Debug.LogError("Error connecting to the database: " + ex.Message); // } // finally // { // connection.Close(); // } // } //} //public void 讀取圖片() //{ // string connectionString = "Data Source=106.1.48.106,4567;Initial Catalog=OW-ERP-SYS;User ID=B70340;Password=Lee0911274990"; // using (SqlConnection connection = new SqlConnection(connectionString)) // { // try // { // connection.Open(); // string query = "SELECT 音檔 FROM 測試錄音檔 WHERE 名稱 LIKE '測試'"; // using (SqlCommand command = new SqlCommand(query, connection)) // { // using (SqlDataReader reader = command.ExecuteReader()) // { // if (reader.Read()) // { // 讀取圖片的二進位資料 // byte[] imageData = (byte[])reader["音檔"]; // recordedClip=LoadAudioClip(imageData); // audioSource.clip = LoadAudioClip(imageData); // UpdateProgressBar(); // UpdateTimeText(); // } // } // } // } // catch (Exception ex) // { // Debug.LogError("Error connecting to the database: " + ex.Message); // } // finally // { // connection.Close(); // } // } //} //private AudioClip LoadAudioClip(byte[] audioData) //{ // 將音頻資料轉換為 AudioClip // return WavUtility.ToAudioClip(audioData); //} //public void 上傳1() //{ // string connectionString = "Data Source=106.1.48.106,4567;Initial Catalog=OW-ERP-SYS;User ID=B70340;Password=Lee0911274990"; // Debug.Log(connectionString); // using (SqlConnection connection = new SqlConnection(connectionString)) // { // try // { // connection.Open(); // byte[] imageBytes = 存圖1.EncodeToJPG(); // string query = "INSERT INTO 測試錄音檔 (名稱, 音檔) VALUES (@流水號, @binary_file)"; // using (SqlCommand command = new SqlCommand(query, connection)) // { // 添加流水號參數 // command.Parameters.AddWithValue("@流水號", "測試"); // 添加二進制圖片數據參數 // command.Parameters.AddWithValue("@binary_file", imageBytes); // int rowsAffected = command.ExecuteNonQuery(); // Debug.Log("成功插入 " + rowsAffected + " 行數據"); // } // } // catch (Exception ex) // { // Debug.LogError("Error connecting to the database: " + ex.Message); // } // finally // { // connection.Close(); // } // } //} //public void 讀取圖片1() //{ // 圖1.texture = null; // string connectionString = "Data Source=106.1.48.106,4567;Initial Catalog=OW-ERP-SYS;User ID=B70340;Password=Lee0911274990"; // using (SqlConnection connection = new SqlConnection(connectionString)) // { // try // { // connection.Open(); // string query = "SELECT 音檔 FROM 測試錄音檔 WHERE 名稱 LIKE '測試'"; // using (SqlCommand command = new SqlCommand(query, connection)) // { // using (SqlDataReader reader = command.ExecuteReader()) // { // if (reader.Read()) // { // 讀取圖片的二進位資料 // byte[] imageData = (byte[])reader["音檔"]; // System.IO.File.WriteAllBytes(Application.persistentDataPath + "/pic.jpg", imageData); // Texture2D texture = new Texture2D(1, 1); // texture.LoadImage(imageData); // 將 Texture2D 設置為 RawImage 的 texture // if (texture.width >texture.height) // { // 圖1.rectTransform.sizeDelta = new Vector2(600, 450); // } // else // { // 圖1.rectTransform.sizeDelta = new Vector2(450, 600); // } // 圖1.texture = texture; // } // } // } // } // catch (Exception ex) // { // Debug.LogError("Error connecting to the database: " + ex.Message); // } // finally // { // connection.Close(); // } // } //} //public void OpenNativeCamera() //{ // AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent"); // string action = intentClass.GetStatic("ACTION_IMAGE_CAPTURE"); // AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", action); // AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); // AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity"); // if (intent.Call("resolveActivity", currentActivity.GetStatic("getPackageManager")) != null) // { // currentActivity.Call("startActivity", intent); // } // else // { // 失敗.text="No camera app available."; // } //} //public void OpenCamera() //{ // string packageName = "com.sec.android.app.camera"; // AndroidJavaClass appLauncherClass = new AndroidJavaClass("com.test.install.Install"); // AndroidJavaObject unityContext = GetUnityContext(); // appLauncherClass.CallStatic("openAppByPackageName", unityContext, packageName); // pic = true; //} //void OnApplicationFocus(bool hasFocus) //{ // if (hasFocus) // { // if (pic) // { // 照片欄位新增(); // pic = false; // } // 失敗.text="應用程序獲得焦點。"; // // 在這裡執行應用程序獲得焦點時的操作 // } // else // { // 失敗.text="應用程序失去焦點。"; // // 在這裡執行應用程序失去焦點時的操作 // } //} //private AndroidJavaObject GetUnityContext() //{ // AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); // return unityPlayerClass.GetStatic("currentActivity"); //} public void 開啟相機() { 拍頁.SetActive(true); 返回紐.SetActive(true); 主頁.SetActive(false); 相片選擇頁.SetActive(false); StartCoroutine(open_Camera()); } private IEnumerator open_Camera() { yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);//授權開啟鏡頭 if (Application.HasUserAuthorization(UserAuthorization.WebCam)) { /* (攝影機名稱, 攝影機要拍到的寬度, 攝影機要拍到的高度, 攝影機的FPS) */ myCam = new WebCamTexture(WebCamTexture.devices[0].name, 1080, 1920, 60); 拍照用.texture = myCam; myCam.Play();//開啟攝影機 } } public void 相機鈕() { Texture2D photoTexture = CapturePhoto(); if (photoTexture != null) { if (照片欄數量 < 照片欄Array.Length) { 照片欄數量++; 照片欄新增Array[照片欄數量 - 1].SetActive(false); 照片欄刪除Array[照片欄數量 - 1].SetActive(true); if (照片欄數量 == 照片欄Array.Length) { 文字欄.SetActive(true); } else { 照片欄Array[照片欄數量].SetActive(true); } Texture2D texture = photoTexture; Texture2D texture1 = photoTexture; texture1=ResizeTexture(texture1, 196, 196); DeviceOrientation orientation = Input.deviceOrientation; 失敗1.text += orientation.ToString(); texture =AdjustTextureOrientation(texture, orientation); texture1 =AdjustTextureOrientation(texture1, orientation); 上傳圖Array[照片欄數量 - 1] = texture; 縮圖Array[照片欄數量 - 1].texture = texture1; 相片選擇頁.SetActive(false); } } myCam.Stop(); myCam = null; 拍頁.SetActive(false); 主頁.SetActive(true); Texture2D AdjustTextureOrientation(Texture2D originalTexture, DeviceOrientation orientation) { Texture2D adjustedTexture = new Texture2D(originalTexture.width, originalTexture.height); switch (orientation) { case DeviceOrientation.LandscapeLeft: // 顺时针旋转90度 adjustedTexture = RotateTexture1(originalTexture, 90f); break; case DeviceOrientation.LandscapeRight: // 逆时针旋转90度 adjustedTexture = RotateTexture1(originalTexture, -90f); break; case DeviceOrientation.PortraitUpsideDown: // 旋转180度 adjustedTexture = RotateTexture1(originalTexture, 180f); break; default: // 其他情况下,返回原始图片 adjustedTexture = originalTexture; break; } return adjustedTexture; } Texture2D CapturePhoto() { if (myCam != null) { int width = myCam.width; int height = myCam.height; // 创建一个新的 Texture2D,并读取当前帧的像素 Texture2D photoTexture = new Texture2D(width, height); photoTexture.SetPixels(myCam.GetPixels()); photoTexture.Apply(); Texture2D rotatedTexture = RotateTexture(photoTexture, true); return rotatedTexture; } return null; } Texture2D ResizeTexture(Texture2D originalTexture, int newWidth, int newHeight) { Texture2D resizedTexture = new Texture2D(newWidth, newHeight, originalTexture.format, true); Color[] pixels = new Color[newWidth * newHeight]; float incX = ((float)1 / originalTexture.width) * ((float)originalTexture.width / newWidth); float incY = ((float)1 / originalTexture.height) * ((float)originalTexture.height / newHeight); for (int x = 0; x < newWidth; x++) { for (int y = 0; y < newHeight; y++) { pixels[y * newWidth + x] = originalTexture.GetPixelBilinear(incX * x, incY * y); } } resizedTexture.SetPixels(pixels); resizedTexture.Apply(); return resizedTexture; } Texture2D RotateTexture(Texture2D originalTexture, bool clockwise) { int width = originalTexture.width; int height = originalTexture.height; Texture2D rotatedTexture = new Texture2D(height, width); Color32[] originalPixels = originalTexture.GetPixels32(); Color32[] rotatedPixels = new Color32[width * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int newX = clockwise ? y : height - y - 1; int newY = clockwise ? width - x - 1 : x; rotatedPixels[newY * height + newX] = originalPixels[y * width + x]; } } rotatedTexture.SetPixels32(rotatedPixels); rotatedTexture.Apply(); return rotatedTexture; } Texture2D RotateTexture1(Texture2D originalTexture, float angle) { // Calculate the dimensions of the rotated texture int width = originalTexture.width; int height = originalTexture.height; float rotatedWidth = Mathf.Abs(width * Mathf.Cos(angle * Mathf.Deg2Rad)) + Mathf.Abs(height * Mathf.Sin(angle * Mathf.Deg2Rad)); float rotatedHeight = Mathf.Abs(width * Mathf.Sin(angle * Mathf.Deg2Rad)) + Mathf.Abs(height * Mathf.Cos(angle * Mathf.Deg2Rad)); // Create a new texture to store rotated pixels Texture2D rotatedTexture = new Texture2D(Mathf.RoundToInt(rotatedWidth), Mathf.RoundToInt(rotatedHeight)); // Get the pixel data of the original texture Color32[] pixels = originalTexture.GetPixels32(); Color32[] rotatedPixels = new Color32[Mathf.RoundToInt(rotatedWidth) * Mathf.RoundToInt(rotatedHeight)]; // Calculate the center of the original texture float centerX = width / 2f; float centerY = height / 2f; // Iterate over each pixel in the rotated texture for (int x = 0; x < rotatedTexture.width; x++) { for (int y = 0; y < rotatedTexture.height; y++) { // Calculate the coordinates of the pixel in the original texture float originalX = Mathf.Cos(-angle * Mathf.Deg2Rad) * (x - rotatedWidth / 2) - Mathf.Sin(-angle * Mathf.Deg2Rad) * (y - rotatedHeight / 2) + centerX; float originalY = Mathf.Sin(-angle * Mathf.Deg2Rad) * (x - rotatedWidth / 2) + Mathf.Cos(-angle * Mathf.Deg2Rad) * (y - rotatedHeight / 2) + centerY; // Get the pixel color from the original texture and assign it to the rotated texture if (originalX >= 0 && originalX < width && originalY >= 0 && originalY < height) { int index = Mathf.RoundToInt(originalY) * width + Mathf.RoundToInt(originalX); rotatedPixels[y * rotatedTexture.width + x] = pixels[index]; } else { // If the coordinates are outside the bounds of the original texture, set the pixel color to transparent rotatedPixels[y * rotatedTexture.width + x] = new Color32(0, 0, 0, 0); } } } // Set the rotated pixels to the rotated texture and apply changes rotatedTexture.SetPixels32(rotatedPixels); rotatedTexture.Apply(); return rotatedTexture; } } private IEnumerator WaitForLocationService() { float latitude = 0; float longitude = 0; if (Input.location.isEnabledByUser) { while (Input.location.status == LocationServiceStatus.Initializing) { yield return null; } // 检查位置服务是否可用 if (Input.location.isEnabledByUser) { // 获取当前位置信息 latitude = Input.location.lastData.latitude; longitude = Input.location.lastData.longitude; 顯示2.text += "Latitude: " + latitude.ToString() +"\n\rLongitude: " + longitude.ToString(); } else { Debug.LogWarning("Location services are not enabled."); } // 停止位置服务 Input.location.Stop(); yield return StartCoroutine(GetGeocodingData(latitude, longitude)); } else { // 提示用户启用位置服务 Debug.LogWarning("Location services are not enabled."); } } private IEnumerator GetGeocodingData(float latitude, float longitude) { string apiKey = "AIzaSyANrU_RGJBK4gPsqKYPZKwljvOqJvrfXi4"; string url= $"https://maps.googleapis.com/maps/api/geocode/json?latlng={latitude},{longitude}&key={apiKey}"; using (UnityWebRequest www = UnityWebRequest.Get(url)) { yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError) { Debug.LogError("Error: " + www.error); } else { // 解析 JSON 响应 string jsonResponse = www.downloadHandler.text; //顯示2.text = "\n\r" + jsonResponse; ParseGeocodingResponse(jsonResponse); // 在这里处理 JSON 响应,提取地址信息 } } } private void ParseGeocodingResponse(string jsonResponse) { JSONNode locationData = JSON.Parse(jsonResponse); Debug.Log(locationData); if (locationData["status"].Value == "OK") { JSONArray results = locationData["results"].AsArray; string combinedLocation = ""; foreach (JSONNode result in results) { JSONArray addressComponents = result["address_components"].AsArray; string county = ""; string township = ""; foreach (JSONNode component in addressComponents) { JSONArray types = component["types"].AsArray; string longName = component["long_name"]; // 檢查是否為 administrative_area_level_1 或 administrative_area_level_2 if (types != null && types.Count > 0) { foreach (JSONNode type in types) { if (type.Value == "administrative_area_level_1") { county = longName; } else if (type.Value == "administrative_area_level_2") { township = longName; } } } } if (!string.IsNullOrEmpty(county) && !string.IsNullOrEmpty(township)) { bool containsChinese = Regex.IsMatch(county, @"[\u4e00-\u9fa5]"); bool containsChinese1 = Regex.IsMatch(township, @"[\u4e00-\u9fa5]"); if (containsChinese && containsChinese1) { combinedLocation = county + "+" + township; 地址1=county; 地址2=township; Debug.Log("縣和鄉的地理位置:" + combinedLocation); 顯示2.text += "\n\r縣和鄉的地理位置:" + combinedLocation; break; // 出現1次就好,所以在這裡退出迴圈 } } } if (string.IsNullOrEmpty(combinedLocation)) { foreach (JSONNode result in results) { JSONArray addressComponents = result["address_components"].AsArray; string county = ""; string township = ""; foreach (JSONNode component in addressComponents) { JSONArray types = component["types"].AsArray; string shortName = component["short_name"]; // 檢查是否為 administrative_area_level_1 或 administrative_area_level_2 if (types != null && types.Count > 0) { foreach (JSONNode type in types) { if (type.Value == "administrative_area_level_1") { county = shortName; } else if (type.Value == "administrative_area_level_2") { township = shortName; } } } } if (!string.IsNullOrEmpty(county) && !string.IsNullOrEmpty(township)) { combinedLocation = county + "+" + township; 地址1=county; 地址2=township; Debug.Log("縣和鄉的地理位置:" + combinedLocation); break; // 出現1次就好,所以在這裡退出迴圈 } } } } else { Debug.Log("找不到縣和鄉的地理位置"); } } public void 新增貼文() { Debug.Log(照片欄數量); if (照片欄數量 == 0) { 彈跳面板開啟("至少新增一張相片!!",false,false,true,() => { },() => { },彈跳面板關閉); } else { 讀取面板.SetActive(true); 地址1 = ""; 地址2 = ""; for (int i = 0; i < 圖片流水.Length; i++) { 圖片流水[i] = ""; } 錄音流水 = ""; 控制表單號 = ""; StartCoroutine(新增貼文流程()); } } private IEnumerator 新增貼文流程() { Input.location.Start(); yield return StartCoroutine(WaitForLocationService()); Set_控制表單號(); if (recordedClip != null) { SQL_CommString.SQL_連線字串_錄音_SQL(Main.Global.伺服器, 錄音資料庫名稱); Set_錄音流水號(); byte[] wavData = WavUtility.FromAudioClip(recordedClip); SQL_game_sys.SQL_新增錄音(錄音流水, wavData, 控制表單號); } for (int i = 0; i < 照片欄數量; i++) { SQL_CommString.SQL_連線字串_圖片_SQL(Main.Global.伺服器, 圖片資料庫名稱); Set_圖片流水號(i); byte[] imageBytes = 上傳圖Array[i].EncodeToJPG(); SQL_game_sys.SQL_新增圖片(圖片流水[i], imageBytes, 控制表單號); } string currentTime = DateTime.Now.ToString("yyyyMMdd-HHmmss"); SQL_game_sys.SQL_新增貼文(控制表單號, currentTime, 貼文內容.text, 圖片流水[0], 圖片流水[1], 圖片流水[2], 圖片流水[3], 圖片流水[4] , 錄音流水, 地址1, 地址2, Main.Global.使用者UID, 圖片資料庫名稱, 錄音資料庫名稱); Main.change_Secen(0); } public void back() { if (拍頁.activeSelf) { myCam.Stop(); myCam = null; 拍頁.SetActive(false); 相片選擇頁.SetActive(false); 主頁.SetActive(true); } else { if (照片欄數量 == 0 && 貼文內容.text =="" && recordedClip == null) { Main.change_Secen(0); } else { 彈跳面板開啟("有讀取到內容,是否要放棄編輯", true, true, false, back1, 彈跳面板關閉, () => { }); } } } private void back1() { Main.change_Secen(0); } public void 彈跳面板開啟(string str,bool 是 , bool 否, bool 叉, Action 是監聽, Action 否監聽, Action 叉監聽) { 彈跳面板.SetActive(true); 主頁.SetActive(false); 返回紐.SetActive(false); 彈跳是.gameObject.SetActive(是); 彈跳否.gameObject.SetActive(否); 彈跳叉.gameObject.SetActive(叉); 彈跳文字.text=str; void 叉監聽器() { 叉監聽(); // 在這裡添加任何你需要的額外邏輯 // 現在你可以輕鬆地刪除監聽器 彈跳叉.onClick.RemoveListener(叉監聽器); } void 是監聽器() { 是監聽(); // 在這裡添加任何你需要的額外邏輯 // 現在你可以輕鬆地刪除監聽器 彈跳是.onClick.RemoveListener(是監聽器); } void 否監聽器() { 否監聽(); // 在這裡添加任何你需要的額外邏輯 // 現在你可以輕鬆地刪除監聽器 彈跳否.onClick.RemoveListener(否監聽器); } // 將監聽器添加到按鈕點擊事件中 彈跳叉.onClick.AddListener(叉監聽器); 彈跳是.onClick.AddListener(是監聽器); 彈跳否.onClick.AddListener(否監聽器); } public void 彈跳面板關閉() { 主頁.SetActive(true); 返回紐.SetActive(true); 彈跳面板.SetActive(false); 彈跳文字.text=""; } private void Set_錄音流水號() { SQL_game_sys.SQL_查詢錄音流水號(); if (SQL_Module.dr.Read()) { string 流水 = SQL_Module.dr["錄音流水號"].ToString(); double 流水號數字部分 = double.Parse(流水.Substring(1)); double 新流水號數字部分 = 流水號數字部分 + 1; string 新流水號數字部分字串 = 新流水號數字部分.ToString().PadLeft(8, '0'); 錄音流水 = "V" + 新流水號數字部分字串; } else { 錄音流水 ="V00000000"; } } private void Set_圖片流水號(int i) { SQL_game_sys.SQL_查詢圖片流水號(); if (SQL_Module.dr.Read()) { string 流水 = SQL_Module.dr["圖片流水號"].ToString(); double 流水號數字部分 = double.Parse(流水.Substring(1)); double 新流水號數字部分 = 流水號數字部分 + 1; string 新流水號數字部分字串 = 新流水號數字部分.ToString().PadLeft(8, '0'); 圖片流水[i] = "P" + 新流水號數字部分字串; } else { 圖片流水[i] ="P00000000"; } } private void Set_控制表單號() { string date = DateTime.Today.ToString("yyyyMMdd"); SQL_game_sys.SQL_查詢貼文流水號(date); if (SQL_Module.dr.Read()) { string 流水 = SQL_Module.dr["控制表單號"].ToString(); // 將流水號轉換為字串 string parts = 流水.Substring(流水.Length - 8); double 流水號數字部分 = double.Parse(parts); double 新流水號數字部分 = 流水號數字部分 + 1; string 新流水號數字部分字串 = 新流水號數字部分.ToString().PadLeft(8, '0'); 控制表單號 = "A-" + date + "-" + 新流水號數字部分字串; } else { 控制表單號 = "A-" + date + "-00000001"; } } public void 截圖() { Main.截圖(); } }