mirror of
https://github.com/0015/ThatProject.git
synced 2026-01-12 09:17:42 +03:00
ESP32CAM | Android(Flutter App) Wired Communication - Base64 Encoding/Decoding [2/2]
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
ESP32CAM | Android(Flutter App) Wired Communication - Baud Rate Test [1/2]
|
ESP32CAM | Android(Flutter App) Wired Communication - Baud Rate Test [1/2]
|
||||||
https://youtu.be/Mod9gX7NWA8
|
https://youtu.be/Mod9gX7NWA8
|
||||||
Created by Eric Nam (ThatProject)
|
Created by Eric N. (ThatProject)
|
||||||
*/
|
*/
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
ESP32CAM | Android(Flutter App) Wired Communication - Base64 Encoding/Decoding [2/2]
|
||||||
|
Video Tutorial: https://youtu.be/-jygTxRmroA
|
||||||
|
Created by Eric N. (ThatProject)
|
||||||
|
*/
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "esp_camera.h"
|
||||||
|
#include <base64.h>
|
||||||
|
#define CAMERA_MODEL_AI_THINKER
|
||||||
|
//#define TTGO_T_CAMERA_PLUS
|
||||||
|
#include "camera_pins2.h"
|
||||||
|
|
||||||
|
#define USE_TFT_ESPI 0
|
||||||
|
|
||||||
|
#if USE_TFT_ESPI
|
||||||
|
#include <TFT_eSPI.h>
|
||||||
|
#include <TJpg_Decoder.h>
|
||||||
|
TFT_eSPI tft = TFT_eSPI();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BAUD_RATE 2000000
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(BAUD_RATE);
|
||||||
|
|
||||||
|
displayInit();
|
||||||
|
cameraInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
grabImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cameraInit(){
|
||||||
|
camera_config_t config;
|
||||||
|
config.ledc_channel = LEDC_CHANNEL_0;
|
||||||
|
config.ledc_timer = LEDC_TIMER_0;
|
||||||
|
config.pin_d0 = Y2_GPIO_NUM;
|
||||||
|
config.pin_d1 = Y3_GPIO_NUM;
|
||||||
|
config.pin_d2 = Y4_GPIO_NUM;
|
||||||
|
config.pin_d3 = Y5_GPIO_NUM;
|
||||||
|
config.pin_d4 = Y6_GPIO_NUM;
|
||||||
|
config.pin_d5 = Y7_GPIO_NUM;
|
||||||
|
config.pin_d6 = Y8_GPIO_NUM;
|
||||||
|
config.pin_d7 = Y9_GPIO_NUM;
|
||||||
|
config.pin_xclk = XCLK_GPIO_NUM;
|
||||||
|
config.pin_pclk = PCLK_GPIO_NUM;
|
||||||
|
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||||
|
config.pin_href = HREF_GPIO_NUM;
|
||||||
|
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||||
|
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||||
|
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||||
|
config.pin_reset = RESET_GPIO_NUM;
|
||||||
|
config.xclk_freq_hz = 10000000;
|
||||||
|
config.pixel_format = PIXFORMAT_JPEG;
|
||||||
|
config.frame_size = FRAMESIZE_QVGA; //320x240
|
||||||
|
config.jpeg_quality = 10;
|
||||||
|
config.fb_count = 2;
|
||||||
|
|
||||||
|
esp_err_t err = esp_camera_init(&config);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_t * s = esp_camera_sensor_get();
|
||||||
|
s->set_hmirror(s, 1);
|
||||||
|
s->set_vflip(s, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void grabImage(){
|
||||||
|
|
||||||
|
camera_fb_t* fb = esp_camera_fb_get();
|
||||||
|
if(!fb || fb->format != PIXFORMAT_JPEG){
|
||||||
|
}else{
|
||||||
|
#if USE_TFT_ESPI
|
||||||
|
TJpgDec.drawJpg(-40, 0, (const uint8_t*)fb->buf, fb->len);
|
||||||
|
#else
|
||||||
|
delay(40);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String encoded = base64::encode(fb->buf, fb->len);
|
||||||
|
Serial.write(encoded.c_str(), encoded.length());
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
esp_camera_fb_return(fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap){
|
||||||
|
#if USE_TFT_ESPI
|
||||||
|
if( y>= tft.height()) return 0;
|
||||||
|
tft.pushImage(x, y, w, h, bitmap);
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayInit(){
|
||||||
|
#if USE_TFT_ESPI
|
||||||
|
tft.begin();
|
||||||
|
tft.setRotation(0);
|
||||||
|
tft.fillScreen(TFT_WHITE);
|
||||||
|
|
||||||
|
TJpgDec.setJpgScale(1);
|
||||||
|
TJpgDec.setSwapBytes(true);
|
||||||
|
TJpgDec.setCallback(tft_output);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 21
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 19
|
||||||
|
#define Y4_GPIO_NUM 18
|
||||||
|
#define Y3_GPIO_NUM 5
|
||||||
|
#define Y2_GPIO_NUM 4
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_ESP_EYE)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 4
|
||||||
|
#define SIOD_GPIO_NUM 18
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 36
|
||||||
|
#define Y8_GPIO_NUM 37
|
||||||
|
#define Y7_GPIO_NUM 38
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 35
|
||||||
|
#define Y4_GPIO_NUM 14
|
||||||
|
#define Y3_GPIO_NUM 13
|
||||||
|
#define Y2_GPIO_NUM 34
|
||||||
|
#define VSYNC_GPIO_NUM 5
|
||||||
|
#define HREF_GPIO_NUM 27
|
||||||
|
#define PCLK_GPIO_NUM 25
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 25
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 22
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 22
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||||
|
#define PWDN_GPIO_NUM 32
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 0
|
||||||
|
#define SIOD_GPIO_NUM 26
|
||||||
|
#define SIOC_GPIO_NUM 27
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 35
|
||||||
|
#define Y8_GPIO_NUM 34
|
||||||
|
#define Y7_GPIO_NUM 39
|
||||||
|
#define Y6_GPIO_NUM 36
|
||||||
|
#define Y5_GPIO_NUM 21
|
||||||
|
#define Y4_GPIO_NUM 19
|
||||||
|
#define Y3_GPIO_NUM 18
|
||||||
|
#define Y2_GPIO_NUM 5
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 23
|
||||||
|
#define PCLK_GPIO_NUM 22
|
||||||
|
|
||||||
|
#elif defined(TTGO_T_CAMERA_PLUS)
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM -1
|
||||||
|
#define XCLK_GPIO_NUM 4
|
||||||
|
#define SIOD_GPIO_NUM 18
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
#define Y9_GPIO_NUM 36
|
||||||
|
#define Y8_GPIO_NUM 37
|
||||||
|
#define Y7_GPIO_NUM 38
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 35
|
||||||
|
#define Y4_GPIO_NUM 26
|
||||||
|
#define Y3_GPIO_NUM 13
|
||||||
|
#define Y2_GPIO_NUM 34
|
||||||
|
#define VSYNC_GPIO_NUM 5
|
||||||
|
#define HREF_GPIO_NUM 27
|
||||||
|
#define PCLK_GPIO_NUM 25
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Camera model not selected"
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.lock
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Visual Studio Code related
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Flutter repo-specific
|
||||||
|
/bin/cache/
|
||||||
|
/bin/internal/bootstrap.bat
|
||||||
|
/bin/internal/bootstrap.sh
|
||||||
|
/bin/mingit/
|
||||||
|
/dev/benchmarks/mega_gallery/
|
||||||
|
/dev/bots/.recipe_deps
|
||||||
|
/dev/bots/android_tools/
|
||||||
|
/dev/devicelab/ABresults*.json
|
||||||
|
/dev/docs/doc/
|
||||||
|
/dev/docs/flutter.docs.zip
|
||||||
|
/dev/docs/lib/
|
||||||
|
/dev/docs/pubspec.yaml
|
||||||
|
/dev/integration_tests/**/xcuserdata
|
||||||
|
/dev/integration_tests/**/Pods
|
||||||
|
/packages/flutter/coverage/
|
||||||
|
version
|
||||||
|
analysis_benchmark.json
|
||||||
|
|
||||||
|
# packages file containing multi-root paths
|
||||||
|
.packages.generated
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
**/generated_plugin_registrant.dart
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
build/
|
||||||
|
flutter_*.png
|
||||||
|
linked_*.ds
|
||||||
|
unlinked.ds
|
||||||
|
unlinked_spec.ds
|
||||||
|
|
||||||
|
# Android related
|
||||||
|
**/android/**/gradle-wrapper.jar
|
||||||
|
**/android/.gradle
|
||||||
|
**/android/captures/
|
||||||
|
**/android/gradlew
|
||||||
|
**/android/gradlew.bat
|
||||||
|
**/android/local.properties
|
||||||
|
**/android/**/GeneratedPluginRegistrant.java
|
||||||
|
**/android/key.properties
|
||||||
|
*.jks
|
||||||
|
|
||||||
|
# iOS/XCode related
|
||||||
|
**/ios/**/*.mode1v3
|
||||||
|
**/ios/**/*.mode2v3
|
||||||
|
**/ios/**/*.moved-aside
|
||||||
|
**/ios/**/*.pbxuser
|
||||||
|
**/ios/**/*.perspectivev3
|
||||||
|
**/ios/**/*sync/
|
||||||
|
**/ios/**/.sconsign.dblite
|
||||||
|
**/ios/**/.tags*
|
||||||
|
**/ios/**/.vagrant/
|
||||||
|
**/ios/**/DerivedData/
|
||||||
|
**/ios/**/Icon?
|
||||||
|
**/ios/**/Pods/
|
||||||
|
**/ios/**/.symlinks/
|
||||||
|
**/ios/**/profile
|
||||||
|
**/ios/**/xcuserdata
|
||||||
|
**/ios/.generated/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
**/ios/Flutter/App.framework
|
||||||
|
**/ios/Flutter/Flutter.framework
|
||||||
|
**/ios/Flutter/Flutter.podspec
|
||||||
|
**/ios/Flutter/Generated.xcconfig
|
||||||
|
**/ios/Flutter/ephemeral
|
||||||
|
**/ios/Flutter/app.flx
|
||||||
|
**/ios/Flutter/app.zip
|
||||||
|
**/ios/Flutter/flutter_assets/
|
||||||
|
**/ios/Flutter/flutter_export_environment.sh
|
||||||
|
**/ios/ServiceDefinitions.json
|
||||||
|
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
**/macos/Flutter/GeneratedPluginRegistrant.swift
|
||||||
|
|
||||||
|
# Coverage
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# Symbols
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Exceptions to above rules.
|
||||||
|
!**/ios/**/default.mode1v3
|
||||||
|
!**/ios/**/default.mode2v3
|
||||||
|
!**/ios/**/default.pbxuser
|
||||||
|
!**/ios/**/default.perspectivev3
|
||||||
|
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||||
|
!/dev/ci/**/Gemfile.lock
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: adc687823a831bbebe28bdccfac1a628ca621513
|
||||||
|
channel: stable
|
||||||
|
|
||||||
|
project_type: app
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# esp32cam_wired_comm
|
||||||
|
|
||||||
|
ESP32CAM Wired Comm
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This project is a starting point for a Flutter application.
|
||||||
|
|
||||||
|
A few resources to get you started if this is your first Flutter project:
|
||||||
|
|
||||||
|
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
||||||
|
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
||||||
|
|
||||||
|
For help getting started with Flutter, view our
|
||||||
|
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
||||||
|
samples, guidance on mobile development, and a full API reference.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
gradle-wrapper.jar
|
||||||
|
/.gradle
|
||||||
|
/captures/
|
||||||
|
/gradlew
|
||||||
|
/gradlew.bat
|
||||||
|
/local.properties
|
||||||
|
GeneratedPluginRegistrant.java
|
||||||
|
|
||||||
|
# Remember to never publicly share your keystore.
|
||||||
|
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||||
|
key.properties
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
def localProperties = new Properties()
|
||||||
|
def localPropertiesFile = rootProject.file('local.properties')
|
||||||
|
if (localPropertiesFile.exists()) {
|
||||||
|
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||||
|
localProperties.load(reader)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||||
|
if (flutterRoot == null) {
|
||||||
|
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||||
|
}
|
||||||
|
|
||||||
|
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||||
|
if (flutterVersionCode == null) {
|
||||||
|
flutterVersionCode = '1'
|
||||||
|
}
|
||||||
|
|
||||||
|
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||||
|
if (flutterVersionName == null) {
|
||||||
|
flutterVersionName = '1.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 30
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
|
applicationId "com.thatproject.esp32cam_wired_comm"
|
||||||
|
minSdkVersion 16
|
||||||
|
targetSdkVersion 30
|
||||||
|
versionCode flutterVersionCode.toInteger()
|
||||||
|
versionName flutterVersionName
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
// TODO: Add your own signing config for the release build.
|
||||||
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility 1.8
|
||||||
|
targetCompatibility 1.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flutter {
|
||||||
|
source '../..'
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.thatproject.esp32cam_wired_comm">
|
||||||
|
<!-- Flutter needs it to communicate with the running application
|
||||||
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
-->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.thatproject.esp32cam_wired_comm">
|
||||||
|
<application
|
||||||
|
android:label="esp32cam_wired_comm"
|
||||||
|
android:icon="@mipmap/ic_launcher">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
android:theme="@style/LaunchTheme"
|
||||||
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
|
the Android process has started. This theme is visible to the user
|
||||||
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
|
to determine the Window background behind the Flutter UI. -->
|
||||||
|
<meta-data
|
||||||
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
|
android:resource="@style/NormalTheme"
|
||||||
|
/>
|
||||||
|
<!-- Displays an Android View that continues showing the launch screen
|
||||||
|
Drawable until Flutter paints its first frame, then this splash
|
||||||
|
screen fades out. A splash screen is useful to avoid any visual
|
||||||
|
gap between the end of Android's launch screen and the painting of
|
||||||
|
Flutter's first frame. -->
|
||||||
|
<meta-data
|
||||||
|
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||||
|
android:resource="@drawable/launch_background"
|
||||||
|
/>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||||
|
android:resource="@xml/device_filter" />
|
||||||
|
</activity>
|
||||||
|
<!-- Don't delete the meta-data below.
|
||||||
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
|
<meta-data
|
||||||
|
android:name="flutterEmbedding"
|
||||||
|
android:value="2" />
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.thatproject.esp32cam_wired_comm;
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity;
|
||||||
|
|
||||||
|
public class MainActivity extends FlutterActivity {
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Modify this file to customize your launch splash screen -->
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="?android:colorBackground" />
|
||||||
|
|
||||||
|
<!-- You can insert your own image assets here -->
|
||||||
|
<!-- <item>
|
||||||
|
<bitmap
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@mipmap/launch_image" />
|
||||||
|
</item> -->
|
||||||
|
</layer-list>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Modify this file to customize your launch splash screen -->
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@android:color/white" />
|
||||||
|
|
||||||
|
<!-- You can insert your own image assets here -->
|
||||||
|
<!-- <item>
|
||||||
|
<bitmap
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@mipmap/launch_image" />
|
||||||
|
</item> -->
|
||||||
|
</layer-list>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 544 B |
Binary file not shown.
|
After Width: | Height: | Size: 442 B |
Binary file not shown.
|
After Width: | Height: | Size: 721 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||||
|
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
|
Flutter draws its first frame -->
|
||||||
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
</style>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||||
|
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
|
Flutter draws its first frame -->
|
||||||
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
</style>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- 0x0403 / 0x6001: FTDI FT232R UART -->
|
||||||
|
<usb-device vendor-id="1027" product-id="24577" />
|
||||||
|
|
||||||
|
<!-- 0x0403 / 0x6015: FTDI FT231X -->
|
||||||
|
<usb-device vendor-id="1027" product-id="24597" />
|
||||||
|
|
||||||
|
<!-- 0x2341 / Arduino -->
|
||||||
|
<usb-device vendor-id="9025" />
|
||||||
|
|
||||||
|
<!-- 0x16C0 / 0x0483: Teensyduino -->
|
||||||
|
<usb-device vendor-id="5824" product-id="1155" />
|
||||||
|
|
||||||
|
<!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
|
||||||
|
<usb-device vendor-id="4292" product-id="60000" />
|
||||||
|
|
||||||
|
<!-- 0x067B / 0x2303: Prolific PL2303 -->
|
||||||
|
<usb-device vendor-id="1659" product-id="8963" />
|
||||||
|
|
||||||
|
<!-- 0x1366 / 0x0105: Segger JLink -->
|
||||||
|
<usb-device vendor-id="4966" product-id="261" />
|
||||||
|
|
||||||
|
<!-- 0x1366 / 0x0105: CH340 JLink -->
|
||||||
|
<usb-device vendor-id="1A86" product-id="7523" />
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.thatproject.esp32cam_wired_comm">
|
||||||
|
<!-- Flutter needs it to communicate with the running application
|
||||||
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
-->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.buildDir = '../build'
|
||||||
|
subprojects {
|
||||||
|
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||||
|
}
|
||||||
|
subprojects {
|
||||||
|
project.evaluationDependsOn(':app')
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
|
android.useAndroidX=true
|
||||||
|
android.enableJetifier=true
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#Fri Jun 23 08:50:38 CEST 2017
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
include ':app'
|
||||||
|
|
||||||
|
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||||
|
def properties = new Properties()
|
||||||
|
|
||||||
|
assert localPropertiesFile.exists()
|
||||||
|
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||||
|
|
||||||
|
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||||
|
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
ESP32CAM | Android(Flutter App) Wired Communication - Base64 Encoding/Decoding [2/2]
|
||||||
|
Video Tutorial: https://youtu.be/-jygTxRmroA
|
||||||
|
Created by Eric N. (ThatProject)
|
||||||
|
*/
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:usb_serial/transaction.dart';
|
||||||
|
import 'package:usb_serial/usb_serial.dart';
|
||||||
|
|
||||||
|
class SerialController extends GetxController {
|
||||||
|
UsbPort _port;
|
||||||
|
StreamSubscription<String> _subscription;
|
||||||
|
Transaction<String> _transaction;
|
||||||
|
int _deviceId;
|
||||||
|
String logMessage = "";
|
||||||
|
final hardwareKeyConnected = false.obs;
|
||||||
|
final base64data = "".obs;
|
||||||
|
|
||||||
|
Future<bool> _connectTo(device) async {
|
||||||
|
if (_subscription != null) {
|
||||||
|
_subscription.cancel();
|
||||||
|
_subscription = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_transaction != null) {
|
||||||
|
_transaction.dispose();
|
||||||
|
_transaction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_port != null) {
|
||||||
|
_port.close();
|
||||||
|
_port = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device == null) {
|
||||||
|
_deviceId = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_port = await device.create();
|
||||||
|
if (!await _port.open()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_deviceId = device.deviceId;
|
||||||
|
|
||||||
|
await _port.setDTR(true);
|
||||||
|
await _port.setRTS(true);
|
||||||
|
await _port.setPortParameters(
|
||||||
|
2000000, UsbPort.DATABITS_8, UsbPort.STOPBITS_1, UsbPort.PARITY_NONE);
|
||||||
|
|
||||||
|
_transaction = Transaction.stringTerminated(
|
||||||
|
_port.inputStream, Uint8List.fromList([13, 10]));
|
||||||
|
|
||||||
|
_subscription = _transaction.stream.listen((String line) {
|
||||||
|
base64data.value = line;
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _getPorts() async {
|
||||||
|
List<UsbDevice> devices = await UsbSerial.listDevices();
|
||||||
|
print(devices);
|
||||||
|
bool targetDeviceFound = false;
|
||||||
|
|
||||||
|
devices.forEach((device) {
|
||||||
|
logMessage = "[Log] device pid: ${device.pid}, device vid: ${device.vid}";
|
||||||
|
if (device.pid == 60000 && device.vid == 4292 || // CP210x UART
|
||||||
|
device.pid == 24577 && device.vid == 1027) // FT232R UART
|
||||||
|
{
|
||||||
|
targetDeviceFound = true;
|
||||||
|
|
||||||
|
if (!hardwareKeyConnected.value) {
|
||||||
|
_connectTo(device).then((res) {
|
||||||
|
hardwareKeyConnected.value = res;
|
||||||
|
Get.snackbar("Device Status", "Connected!",
|
||||||
|
duration: Duration(seconds: 5));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!targetDeviceFound) {
|
||||||
|
hardwareKeyConnected.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendString(String text) async {
|
||||||
|
if (_port == null) return;
|
||||||
|
await _port.write(Uint8List.fromList(text.codeUnits));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
UsbSerial.usbEventStream.listen((UsbEvent event) {
|
||||||
|
_getPorts();
|
||||||
|
});
|
||||||
|
_getPorts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
_connectTo(null);
|
||||||
|
super.onClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
ESP32CAM | Android(Flutter App) Wired Communication - Base64 Encoding/Decoding [2/2]
|
||||||
|
Video Tutorial: https://youtu.be/-jygTxRmroA
|
||||||
|
Created by Eric N. (ThatProject)
|
||||||
|
*/
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:image_gallery_saver/image_gallery_saver.dart';
|
||||||
|
import 'package:pinch_zoom_image_last/pinch_zoom_image_last.dart';
|
||||||
|
import 'package:string_validator/string_validator.dart';
|
||||||
|
|
||||||
|
import 'controller/serial_controller.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
runApp(GetMaterialApp(
|
||||||
|
home: First(),
|
||||||
|
theme: ThemeData.light(),
|
||||||
|
darkTheme: ThemeData.dark(),
|
||||||
|
themeMode: ThemeMode.system,
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
class First extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text("ESP32CAM WIRED COMM APP For QVGA"),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
GetX<SerialController>(
|
||||||
|
init: SerialController(),
|
||||||
|
builder: (_) => Column(
|
||||||
|
children: [
|
||||||
|
Text(_.logMessage),
|
||||||
|
SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Your ESP32CAM Connected?: ${_.hardwareKeyConnected.value.toString().toUpperCase()}',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
_.hardwareKeyConnected.value
|
||||||
|
? Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 32,
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
'Confirm',
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 24),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
Get.to(Second());
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 16),
|
||||||
|
child: Text(
|
||||||
|
'Please connect\nyour ESP32CAM via USB',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 32,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Second extends StatelessWidget {
|
||||||
|
var _bytesImage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
backgroundColor: const Color(0xffffffff),
|
||||||
|
foregroundColor: Colors.black,
|
||||||
|
onPressed: () async {
|
||||||
|
if (_bytesImage == null) return;
|
||||||
|
|
||||||
|
final result = await ImageGallerySaver.saveImage(_bytesImage);
|
||||||
|
Get.snackbar("Image Save", result != null ? "Success!" : "Fail!",
|
||||||
|
duration: Duration(seconds: 3));
|
||||||
|
},
|
||||||
|
child: Icon(Icons.save),
|
||||||
|
),
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Viewer Page'),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Obx(() {
|
||||||
|
final connected =
|
||||||
|
Get.find<SerialController>().hardwareKeyConnected.value;
|
||||||
|
|
||||||
|
if (connected) {
|
||||||
|
final base64data =
|
||||||
|
Get.find<SerialController>().base64data.value.toString();
|
||||||
|
|
||||||
|
if (isBase64(base64data)) {
|
||||||
|
_bytesImage = Base64Decoder().convert(base64data);
|
||||||
|
return showImageWithPinchZoom();
|
||||||
|
} else {
|
||||||
|
return showImageWithPinchZoom();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Get.back();
|
||||||
|
return Text('Disconnected =.=');
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget showImageWithPinchZoom() {
|
||||||
|
return PinchZoomImage(
|
||||||
|
image: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
|
child: Image.memory(
|
||||||
|
_bytesImage,
|
||||||
|
gaplessPlayback: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
zoomedBackgroundColor: Colors.black.withOpacity(0.5),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
name: esp32cam_wired_comm
|
||||||
|
description: ESP32CAM Wired Comm
|
||||||
|
|
||||||
|
# The following line prevents the package from being accidentally published to
|
||||||
|
# pub.dev using `pub publish`. This is preferred for private packages.
|
||||||
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
|
# The following defines the version and build number for your application.
|
||||||
|
# A version number is three numbers separated by dots, like 1.2.43
|
||||||
|
# followed by an optional build number separated by a +.
|
||||||
|
# Both the version and the builder number may be overridden in flutter
|
||||||
|
# build by specifying --build-name and --build-number, respectively.
|
||||||
|
# In Android, build-name is used as versionName while build-number used as versionCode.
|
||||||
|
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
||||||
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
|
# Read more about iOS versioning at
|
||||||
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
|
||||||
|
# The following adds the Cupertino Icons font to your application.
|
||||||
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
cupertino_icons: ^1.0.2
|
||||||
|
usb_serial: ^0.2.4
|
||||||
|
get: ^4.1.4
|
||||||
|
pinch_zoom_image_last: ^0.3.2
|
||||||
|
image_gallery_saver: ^1.6.9
|
||||||
|
string_validator: ^0.3.0
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
# For information on the generic Dart part of this file, see the
|
||||||
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
||||||
|
# The following section is specific to Flutter.
|
||||||
|
flutter:
|
||||||
|
|
||||||
|
# The following line ensures that the Material Icons font is
|
||||||
|
# included with your application, so that you can use the icons in
|
||||||
|
# the material Icons class.
|
||||||
|
uses-material-design: true
|
||||||
|
|
||||||
|
# To add assets to your application, add an assets section, like this:
|
||||||
|
# assets:
|
||||||
|
# - images/a_dot_burr.jpeg
|
||||||
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
|
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||||
|
|
||||||
|
# For details regarding adding assets from package dependencies, see
|
||||||
|
# https://flutter.dev/assets-and-images/#from-packages
|
||||||
|
|
||||||
|
# To add custom fonts to your application, add a fonts section here,
|
||||||
|
# in this "flutter" section. Each entry in this list should have a
|
||||||
|
# "family" key with the font family name, and a "fonts" key with a
|
||||||
|
# list giving the asset and other descriptors for the font. For
|
||||||
|
# example:
|
||||||
|
# fonts:
|
||||||
|
# - family: Schyler
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/Schyler-Regular.ttf
|
||||||
|
# - asset: fonts/Schyler-Italic.ttf
|
||||||
|
# style: italic
|
||||||
|
# - family: Trajan Pro
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/TrajanPro.ttf
|
||||||
|
# - asset: fonts/TrajanPro_Bold.ttf
|
||||||
|
# weight: 700
|
||||||
|
#
|
||||||
|
# For details regarding fonts from package dependencies,
|
||||||
|
# see https://flutter.dev/custom-fonts/#from-packages
|
||||||
Reference in New Issue
Block a user