반응형

The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream.

키보드 입력을 보낸다.


2020/10/17 - [Raspberry Pi & Arduino] - Turn your Arduino Pro Micro into a USB Keyboard - 아두이노 프로 마이크로 USB 키보드 만들기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <Windows.h>
#include <iostream>
 
using namespace std;
 
void PrintMenu()
{
    cout << "--- Key sender ---" << endl << endl;
    cout << "0: End" << endl;
    cout << "1: Send left key" << endl;
    cout << "2: Send right key" << endl;
    cout << "3: Send up key" << endl;
    cout << "4: Send down key" << endl;
    cout << "5: Send enter key" << endl;
    cout << "6: Send 'aA'" << endl;
    cout << "Choose: ";
}
 
// Virtual-Key Codes: https://docs.microsoft.com/ko-kr/windows/win32/inputdev/virtual-key-codes
void SendVKcodes(BYTE vk)
{
    Sleep(5000); // Wait for 5 seconds before sending a keycode.
 
    INPUT input;
    ZeroMemory(&input, sizeof(INPUT));
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = vk;
    // A virtual-key code. The code must be a value in the range 1 to 254. If the dwFlags member
    // specifies KEYEVENTF_UNICODE, wVk must be 0.
 
    // input.ki.wScan = vk;
    // A hardware scan code for the key. If dwFlags specifies KEYEVENTF_UNICODE, wScan specifies
    // a Unicode character which is to be sent to the foreground application.
 
    SendInput(1&input, sizeof(INPUT));
 
    input.ki.dwFlags = KEYEVENTF_KEYUP;
    // If specified, the key is being released. If not specified, the key is being pressed.
    SendInput(1&input, sizeof(INPUT));
}
 
void SendaA()
{
    Sleep(5000);
 
    // Send 'a'
    INPUT input;
    ZeroMemory(&input, sizeof(INPUT));
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = 0x41;    // a key
    SendInput(1&input, sizeof(INPUT));
 
    input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1&input, sizeof(INPUT));
 
    // Sned 'A'
    input.ki.dwFlags = 0;
    input.ki.wVk = VK_SHIFT;
    SendInput(1&input, sizeof(INPUT));
 
    input.ki.wVk = 0x41;    // a key
    SendInput(1&input, sizeof(INPUT));
 
    input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1&input, sizeof(INPUT));
 
    input.ki.wVk = VK_SHIFT;
    SendInput(1&input, sizeof(INPUT));
}
 
int main()
{
    int choice = 1;
 
    while (choice)
    {
        PrintMenu();
        cin >> choice;
 
        switch (choice)
        {
        case 1:
            SendVKcodes(VK_LEFT);
 
            break;
        case 2:
            SendVKcodes(VK_RIGHT);
 
            break;
        case 3:
            SendVKcodes(VK_UP);
 
            break;
        case 4:
            SendVKcodes(VK_DOWN);
 
            break;
        case 5:
            SendVKcodes(VK_RETURN);
 
            break;
 
        case 6:
            SendaA();
 
            break;
        default:
 
            return 0;
        }
    }
 
    return 0;
}




Run the program and choose the key you want to send.


※ Adjust key down duration by adding Sleep() between KEYEVENTF_KEYDOWN and KEYEVENTF_KEYUP.

For short key down duration, give 60~100 to Sleep() for the better result although some keys don't need Sleep() at all for very short key down duration.


반응형
Posted by J-sean
:
반응형

Build a Windows dialog-based OpenCV program.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <Windows.h>
#include <gdiplus.h>
#include <opencv2/opencv.hpp>
#include "resource.h"
 
#pragma comment(lib, "gdiplus")
 
using namespace cv;
using namespace Gdiplus;
 
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
HWND hDlgMain;
 
VideoCapture cap;
Mat frame;
RECT invalidateRect;


Prepare necessities.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    ULONG_PTR gpToken;
    GdiplusStartupInput gpsi;
 
    if (GdiplusStartup(&gpToken, &gpsi, NULL!= Ok) {
        MessageBox(NULL, TEXT("GDI+ start-up error."), TEXT("GDI+ Error"), MB_OK);
    }
 
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MainDlgProc);
    
    GdiplusShutdown(gpToken);
 
    return 0;
}


Start GDI+ and create a modal dialog box from a dialog template resource.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool initCamera()
{
    cap.open(0);
    if (cap.isOpened()) {
        invalidateRect = { 00, cvRound(cap.get(CAP_PROP_FRAME_WIDTH)), cvRound(cap.get(CAP_PROP_FRAME_HEIGHT)) };
 
        return true;
    }
    else {
        MessageBox(NULL, TEXT("Camera open failed."), TEXT("Camera Error"), MB_OK);
 
        return false;
    }    
}


Initiate a camera and set the windows update region.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void OnPaint(HDC hdc)
{
    Graphics G(hdc);
 
    cap >> frame;
    if (frame.empty()) {
        TextOut(hdc, 300240"No frame to show"8);
 
        return;
    }
 
    if (IsDlgButtonChecked(hDlgMain, IDC_CHECK1) == BST_CHECKED) {
        cvtColor(frame, frame, COLOR_BGR2GRAY);
        Canny(frame, frame, 50100);
        cvtColor(frame, frame, COLOR_GRAY2BGRA);
    }
    else {
        cvtColor(frame, frame, COLOR_BGR2BGRA);
    }
 
    Bitmap bitmap(frame.size().width, frame.size().height, frame.step1(), PixelFormat32bppARGB, frame.data);
    G.DrawImage(&bitmap, 00, bitmap.GetWidth(), bitmap.GetHeight());
}


Process each frame and draw it. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static HANDLE hTimer;
 
    switch (iMessage) {
    case WM_INITDIALOG:
        hDlgMain = hDlg;
        if (initCamera()) {
            hTimer = (HANDLE)SetTimer(hDlg, 110NULL);
        }
        else {
            hTimer = NULL;
        }
 
        return TRUE;
 
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
 
            return TRUE;
 
        case IDCANCEL:
            if (hTimer != NULL) {
                KillTimer(hDlg, 1);
            }
            EndDialog(hDlg, IDCANCEL);
 
            return TRUE;
        }
 
    case WM_PAINT:
        hdc = BeginPaint(hDlg, &ps);
        OnPaint(hdc);
        EndPaint(hDlg, &ps);
 
        return TRUE;
 
    case WM_TIMER:
        InvalidateRect(hDlg, &invalidateRect, FALSE);
        return 0;
    }
 
    return FALSE;
}


Create a timer and define the necessary variables and handle window messages.



Run the program.


Check 'Canny Edge Detection'.


반응형
Posted by J-sean
:
반응형

GDI+ Bitmap class inherits from the Image class. The Image class provides methods for loading and saving vector images (metafiles) and raster images (bitmaps). You can build Windows applications with GDI+ and OpenCV.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <windows.h>
#include <gdiplus.h>
#include <opencv2/opencv.hpp>
 
#pragma comment(lib, "gdiplus")
 
using namespace cv;
using namespace Gdiplus;
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCSTR lpszClass = "MatToBitmap";
 
Mat src;    // source image
Mat org;    // original image
Mat dst;    // processed image
 

Prepare necessities.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
 
    ULONG_PTR gpToken;
    GdiplusStartupInput gpsi;
    if (GdiplusStartup(&gpToken, &gpsi, NULL!= Ok) {
        MessageBox(NULL, TEXT("GDI+ start-up error."), TEXT("GDI+ Error"), MB_OK);
 
        return 0;
    }
 
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); //(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hInstance = hInstance;
    WndClass.lpfnWndProc = (WNDPROC)WndProc;
    WndClass.lpszClassName = lpszClass;
    WndClass.lpszMenuName = NULL;
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&WndClass);
 
    hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,
        670340NULL, (HMENU)NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
 
    while (GetMessage(&Message, 000)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
 
    GdiplusShutdown(gpToken);
 
    return (int)Message.wParam;
}
 
 

Start GDI+ and change the background color to the radio button color and Window size.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool getFile(PTCHAR filename)
{
    OPENFILENAME ofn;
    memset(&ofn, 0sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = NULL;
    ofn.lpstrFilter = TEXT("all(*.*)\0*.*\0jpg(*.jpg)\0*.jpg\0png(*.png)\0*.png\0bmp(*.bmp)\0*.bmp\0");
    ofn.lpstrFile = filename;
    ofn.nMaxFile = MAX_PATH;
 
    if (GetOpenFileName(&ofn) != 0) {
        //MessageBox(NULL, filename, TEXT("File opened."), MB_OK);
 
        return true;
    }
    else {
        MessageBox(NULL, TEXT("File open failed"), TEXT("No file selected"), MB_OK);
 
        return false;
    }
}
 
 

Retrieve an image file name.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool ImageLoad()
{
    TCHAR filename[MAX_PATH] = "";
 
    if (getFile(filename)) {
        src = imread(filename);
        if (src.empty()) {
            MessageBox(NULL, TEXT("Image load failed"), TEXT("No image loaded"), MB_OK);
 
            return false;
        }
 
        return true;
    }
    else {
        return false;
    }
}
 
 

Read the image from the file.

 

1
2
3
4
5
6
7
8
void ImageResize()
{
    // maximum image display size: 320 X 240 with original ratio
    double ratio = min((double)320 / (double)src.size().width, (double)240 / (double)src.size().height);
    resize(src, src, cv::Size(), ratio, ratio);
    org = src.clone();
    cvtColor(org, org, COLOR_BGR2BGRA);
}
 
 

Resize an image.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void ImageProcess(int direction)
{
    cvtColor(src, dst, COLOR_BGR2GRAY);
 
    float vertical[] = {
        -202,
        -202,
        -202
    };
 
    float horizontal[] = {
        -2-2-2,
        000,
        222
    };
 
    float diagonal[] = {
        -2-20,
        -202,
        022
    };
    
    Mat emboss;
    switch (direction)
    {
    case 0:
        emboss = Mat(33, CV_32FC1, vertical);
 
        break;
 
    case 1:
        emboss = Mat(33, CV_32FC1, horizontal);
 
        break;
 
    case 2:
        emboss = Mat(33, CV_32FC1, diagonal);
 
        break;
 
    default:
        emboss = Mat(33, CV_32FC1, vertical);
    }
    filter2D(dst, dst, -1, emboss, cv::Point(-1-1), 128);
    
    cvtColor(dst, dst, COLOR_GRAY2BGRA);
}
 
 

Process an image with embossing filter.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void OnPaint(HDC hdc)
{
    if (!dst.empty()) {
        Graphics G(hdc);
 
        Bitmap bitmapDst(dst.size().width, dst.size().height, dst.step, PixelFormat32bppARGB, dst.data);
        Bitmap bitmapOrg(org.size().width, org.size().height, org.step, PixelFormat32bppARGB, org.data);
        // stride(src.step): Integer that specifies the byte offset between the beginning of one scan line and
        // the next. This is usually(but not necessarily) the number of bytes in the pixel format(for example,
        // 2 for 16 bits per pixel) multiplied by the width of the bitmap. The value passed to this parameter
        // must be a multiple of four.
 
        G.DrawImage(&bitmapDst, 00, bitmapDst.GetWidth(), bitmapDst.GetHeight());
        G.DrawImage(&bitmapOrg, bitmapOrg.GetWidth() + 100, bitmapOrg.GetWidth(), bitmapOrg.GetHeight());
    }
    else {
        TextOut(hdc, 270110, TEXT("No image to display"), 19);
    }
}
 
 

Draw original and processed images.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
enum { ID_R1 = 101, ID_R2, ID_R3 };
HWND r1, r2, r3;
int x = 10;
int y = 270;
int w = 90;
int h = 20;
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;    
 
    switch (iMessage) {
    case WM_CREATE:
        if (ImageLoad()) {
            ImageResize();
            ImageProcess(0);
        }
        
        CreateWindow(TEXT("button"), TEXT("Filter type"), WS_CHILD | WS_VISIBLE |
            BS_GROUPBOX, 525029050, hWnd, (HMENU)0, g_hInst, NULL);
 
        r1 = CreateWindow(TEXT("button"), TEXT("Vertical"), WS_CHILD | WS_VISIBLE |
            BS_AUTORADIOBUTTON | WS_GROUP, x, y, w, h, hWnd, (HMENU)ID_R1, g_hInst, NULL);
 
        r2 = CreateWindow(TEXT("button"), TEXT("Horizontal"), WS_CHILD | WS_VISIBLE |
            BS_AUTORADIOBUTTON, x + 90, y, w, h, hWnd, (HMENU)ID_R2, g_hInst, NULL);
 
        r3 = CreateWindow(TEXT("button"), TEXT("Diagonal"), WS_CHILD | WS_VISIBLE |
            BS_AUTORADIOBUTTON, x + 180, y, w, h, hWnd, (HMENU)ID_R3, g_hInst, NULL);
 
        CheckRadioButton(hWnd, ID_R1, ID_R3, ID_R1);
 
        return 0;
 
    case WM_COMMAND:
        if (!dst.empty()) {
            switch (LOWORD(wParam)) {
            case ID_R1:
                ImageProcess(0);
                break;
 
            case ID_R2:
                ImageProcess(1);
                break;
 
            case ID_R3:
                ImageProcess(2);
                break;
            }
 
            InvalidateRect(hWnd, NULL, TRUE);
        }
 
        return 0;
 
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        OnPaint(hdc);
        EndPaint(hWnd, &ps);
 
        return 0;
 
    case WM_DESTROY:
        PostQuitMessage(0);
 
        return 0;
    }
 
    return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
 
 

Define the necessary variables and handle window messages.

 

 

Run the application and select an image file.

 

Processed and original image with a vertical filter.

 

Processed and original image with a horizontal filter.

 

Processed and original image with a diagonal filter.

 

 

반응형
Posted by J-sean
:
반응형

A YouTubePlayer provides methods for loading, playing and controlling YouTube video playback.


Copy 'YouTubeAndroidPlayerApi.jar' to 'app/libs' and sync project with gradle files.


<AndroidManifest.xml>

1
    <uses-permission android:name="android.permission.INTERNET"/>



<activity_main.xml>

1
2
3
4
    <com.google.android.youtube.player.YouTubePlayerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/youTubePlayerView"/>



<MainActivity.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public class MainActivity extends YouTubeBaseActivity {
 
    YouTubePlayerView youTubePlayerView;
    YouTubePlayer player;
 
    private static String API_KEY = "AIyaSyDpsLddBj2ISc-NHU4sxWFh4JlcHNELir8";  // Your API Key
    private static String videoId = "Mx5GmonOiKo"// Youtube video ID from https://youtu.be/Mx5GmonOiKo
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        initPlayer();
 
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loadVideo();
            }
        });
 
        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playVideo();
            }
        });
    }
 
    public void initPlayer() {
        youTubePlayerView = findViewById(R.id.youTubePlayerView);
        youTubePlayerView.initialize(API_KEY, new YouTubePlayer.OnInitializedListener() {
            @Override
            public void onInitializationSuccess(YouTubePlayer.Provider provider, final YouTubePlayer youTubePlayer, boolean b) {
 
                player = youTubePlayer;
 
                youTubePlayer.setPlayerStateChangeListener(new YouTubePlayer.PlayerStateChangeListener() {
                    @Override
                    public void onLoading() {
 
                    }
 
                    @Override
                    public void onLoaded(String s) {
                        Toast.makeText(getApplicationContext(), s + " loaded", Toast.LENGTH_SHORT).show();
                    }
 
                    @Override
                    public void onAdStarted() {
 
                    }
 
                    @Override
                    public void onVideoStarted() {
 
                    }
 
                    @Override
                    public void onVideoEnded() {
 
                    }
 
                    @Override
                    public void onError(YouTubePlayer.ErrorReason errorReason) {
 
                    }
                });
            }
 
            @Override
            public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
 
            }
        });
    }
 
    public void loadVideo() {
        if (player != null) {
            player.cueVideo(videoId);
            // Loads the specified video's thumbnail and prepares the player to play the video, but does not download any of the video stream
            // until play() is called.
        }
    }
 
    public void playVideo() {
        if (player != null) {
            if (player.isPlaying()) {
                player.pause();
            } else {
                player.play();
            }
        }
    }
}


Your activity needs to extend YouTubeBaseActivity.



Run the app and click the LOAD button.


It loads the video.


Play and enjoy the video.


반응형
Posted by J-sean
:
반응형

You can stream a video file with VideoView.


<AndroidManifest.xml>

1
    <uses-permission android:name="android.permission.INTERNET"/>



<MainActivity.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class MainActivity extends AppCompatActivity {
 
    VideoView videoView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        videoView = findViewById(R.id.videoView);
 
        MediaController mediaController = new MediaController(this);
        videoView.setMediaController(mediaController);
 
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                videoView.setVideoURI(Uri.parse("http://nexoft.tk/data/WhileYouWereSleeping.mp4")); // or your video file url.
                videoView.requestFocus();
                videoView.start();
            }
        });
 
        videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                Toast.makeText(getApplicationContext(), "Video play completed", Toast.LENGTH_SHORT).show();
            }
        });
 
        videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                String message;
 
                switch (what) {
                    case MediaPlayer.MEDIA_ERROR_UNKNOWN:
                        message = "MEDIA_ERROR_UNKNOWN";
                        break;
 
                    case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
                        message = "MEDIA_ERROR_SERVER_DIED";
                        break;
 
                    default:
                        message = "No what";
                }
 
                switch (extra) {
                    case MediaPlayer.MEDIA_ERROR_IO:
                        message += ", MEDIA_ERROR_IO";
                        break;
 
                    case MediaPlayer.MEDIA_ERROR_MALFORMED:
                        message += ", MEDIA_ERROR_MALFORMED";
                        break;
 
                    case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
                        message += ", MEDIA_ERROR_UNSUPPORTED";
                        break;
 
                    case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
                        message += ", MEDIA_ERROR_TIMED_OUT";
                        break;
 
                    default:
                        message += ", No extra";
                }
                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
 
                //    Returns true if the method handled the error, false if it didn't. Returning false, or not having an OnErrorListener
                //    at all, will cause the OnCompletionListener to be called.
                return true;
            }
        });
    }
}




Run the app and click the PLAY button.


It may not be able to stream the video and show an error message in AVD.


It can stream the video in the actual device.


반응형
Posted by J-sean
:
반응형

You can stream an audio file with MediaPlayer.


<AndroidManifest.xml>

1
    <uses-permission android:name="android.permission.INTERNET"/>



<MainActivity.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public class MainActivity extends AppCompatActivity {
 
    MediaPlayer mediaPlayer;
    int position = 0;
    boolean isPaused = false;   // To prevent false resume.
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // Play
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                if (mediaPlayer != null) {
                    mediaPlayer.release();
                }
                try {
                    mediaPlayer = new MediaPlayer();
                    mediaPlayer.setDataSource("http://nexoft.tk/download/Davich.mp3");  // or your audio file url.
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                    isPaused = false;
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
                Toast.makeText(getApplicationContext(), "Media player started", Toast.LENGTH_SHORT).show();
            }
        });
 
        // Stop
        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    isPaused = false;
                    Toast.makeText(getApplicationContext(), "Media player stopped", Toast.LENGTH_SHORT).show();
                }
            }
        });
 
        // Pause
        Button button3 = findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    position = mediaPlayer.getCurrentPosition();
                    mediaPlayer.pause();
                    isPaused = true;
                    Toast.makeText(getApplicationContext(), "Media player paused at " + position / 1000 + " sec", Toast.LENGTH_SHORT).show();
                }
            }
        });
 
        // Resume
        Button button4 = findViewById(R.id.button4);
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mediaPlayer != null && !mediaPlayer.isPlaying() && isPaused == true) {
                    mediaPlayer.start();
                    mediaPlayer.seekTo(position);
                    isPaused = false;
                    Toast.makeText(getApplicationContext(), "Media player resumed at " + position / 1000 + " sec", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
 
        if (mediaPlayer != null) {
            mediaPlayer.release();
        }
    }
}




Run the app and start the audio file.


반응형
Posted by J-sean
:
반응형

Build a windows dialog-based OpenCV perspective transform program.


Change Subsystem setting from Console to Windows if necessary.


Add a resource and create a dialog box.


Include and declare necessities.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <Windows.h>
#include <opencv2/opencv.hpp>
#include "resource.h"
 
using namespace cv;
 
bool getFile(PTCHAR filename);
void onMouse(int event, int x, int y, int flags, void* userdata);
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
 
HWND hDlgMain;
 
Mat sourceImage;
Mat targetImage;
// TTC card ratio
int width = 850;
int height = 550;
Point2f srcQuad[4], dstQuad[4];



Define WinMain which calls getFile() and DialogBox().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    TCHAR filename[MAX_PATH] = "";
    if (!getFile(filename)) {
        return -1;
    }
 
    sourceImage = imread(filename);
    if (sourceImage.empty()) {
        MessageBox(NULL, TEXT("Image load failed"), TEXT("No image loaded"), MB_OK);
 
        return -1;
    }
 
    namedWindow("sourceImage");
    setMouseCallback("sourceImage", onMouse);
 
    imshow("sourceImage", sourceImage);
 
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MainDlgProc);
 
    return 0;
}



getFile() retrieves an image file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool getFile(PTCHAR filename)
{
    OPENFILENAME ofn;
    memset(&ofn, 0sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = NULL;
    ofn.lpstrFilter = TEXT("all(*.*)\0*.*\0jpg(*.jpg)\0*.jpg\0png(*.png)\0*.png\0bmp(*.bmp)\0*.bmp\0");
    ofn.lpstrFile = filename;
    ofn.nMaxFile = MAX_PATH;
 
    if (GetOpenFileName(&ofn) != 0) {
        //MessageBox(NULL, filename, TEXT("File opened."), MB_OK);
 
        return true;
    }
    else {
        MessageBox(NULL, TEXT("File open failed"), TEXT("No file selected"), MB_OK);
 
        return false;
    }
}



Define a mouse callback function that processes perspective transform.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void onMouse(int event, int x, int y, int flags, void* userdata)
{
    static int cnt = 0;
 
    if (event == EVENT_LBUTTONDOWN) {
        if (cnt < 4) {
            srcQuad[cnt++= Point2f(x, y);
 
            circle(sourceImage, Point2f(x, y), 3, Scalar(00255), -1);
            imshow("sourceImage", sourceImage);
 
            if (cnt == 4) {
                /*
                width = max(
                    sqrt(pow(srcQuad[0].x - srcQuad[1].x, 2)) + sqrt(pow(srcQuad[0].y - srcQuad[1].y, 2)),
                    sqrt(pow(srcQuad[2].x - srcQuad[3].x, 2)) + sqrt(pow(srcQuad[2].y - srcQuad[3].y, 2))
                );
                height = max(
                    sqrt(pow(srcQuad[1].x - srcQuad[2].x, 2)) + sqrt(pow(srcQuad[1].y - srcQuad[2].y, 2)),
                    sqrt(pow(srcQuad[3].x - srcQuad[0].x, 2)) + sqrt(pow(srcQuad[3].y - srcQuad[0].y, 2))
                );
                */            
 
                dstQuad[0= Point2f(00);
                dstQuad[1= Point2f(width - 10);
                dstQuad[2= Point2f(width - 1, height - 1);
                dstQuad[3= Point2f(0, height - 1);
 
                Mat perspectiveTransform = getPerspectiveTransform(srcQuad, dstQuad);
 
                warpPerspective(sourceImage, targetImage, perspectiveTransform, Size(width, height));
 
                cnt = 0;
                
                imshow("targetImage", targetImage);
            }
        }
    }
}



Dialog box procedure sets and/or retrieves target image width and height value from the dialog. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    switch (iMessage) {
    case WM_INITDIALOG:
        hDlgMain = hDlg;
        SetDlgItemInt(hDlg, IDC_WIDTH, width, FALSE);
        SetDlgItemInt(hDlg, IDC_HEIGHT, height, FALSE);
 
        return TRUE;
 
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
            width = GetDlgItemInt(hDlg, IDC_WIDTH, NULL, FALSE);
            height = GetDlgItemInt(hDlg, IDC_HEIGHT, NULL, FALSE);
 
            return TRUE;
 
        case IDCLOSE:
            EndDialog(hDlg, IDOK);
 
            return TRUE;
        }
    }
 
    return FALSE;
}




Run the program and select an image file.


You can change the target image size or just leave it.


Source image window.


Choose four corners from the left-top to clockwise.


Perspective transform processed image.


반응형
Posted by J-sean
:
반응형

Explains how to take a photo and save the full-size photo in an easy way.


기기의 카메라 앱을 실행 시키고 사진을 찍어 앱 디렉토리에 저장하고 화면에 표시 한다.


<AndroidManifest.xml>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    <!-- The write permission implicitly allows reading, so if you need to write
    to the external storage then you need to request only one permission: -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 
    <uses-feature android:name="android.hardware.camera"
                  android:required="true"/>
 
    <application
        ...
        <provider
            android:authorities="com.example.myapplication.fileprovider"
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths">
            </meta-data>
        </provider>
        ...
    </application>



<res/xml/file_paths.xml>

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="my_images"
        path="Android/data/com.example.myapplication/files/Pictures"/>
</paths>



<MainActivity.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
public class MainActivity extends AppCompatActivity {
 
    static final int PERMISSION_REQUEST_CONTACTS = 1001;
    static final int REQUEST_TAKE_PHOTO = 2001;
 
    ImageView imageView;
    String currentPhotoPath;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        String[] permissionRequests = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
 
        checkPermissions(permissionRequests);
 
        imageView = findViewById(R.id.imageView);
        Button button = findViewById(R.id.button);
 
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (intent.resolveActivity(getPackageManager()) != null) {
                    File photoFile = null;
                    try {
                        photoFile = createImageFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    if (photoFile != null) {
                        Uri photoURI = FileProvider.getUriForFile(getApplicationContext(),
                                "com.example.myapplication.fileprovider", photoFile);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                        startActivityForResult(intent, REQUEST_TAKE_PHOTO);
                    }
                }
            }
        });
    }
 
    public void checkPermissions(String[] permissionRequests) {
        final ArrayList<String> permissionRequestList = new ArrayList<String>();
 
        for (final String request : permissionRequests) {
            if (ContextCompat.checkSelfPermission(this, request) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, request)) {   // Redundant in this case
                    permissionRequestList.add(request);
                } else {
                    permissionRequestList.add(request);
                }
            }
        }
 
        if (!permissionRequestList.isEmpty()) {
            final String[] results = new String[permissionRequestList.size()];
            permissionRequestList.toArray(results);
 
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("info");
 
            String msg = "This app won't work properly unless you grant below permissions.";
            for (String str : results)
                msg += ("\n- "+ str);
 
            builder.setMessage(msg);
            builder.setIcon(android.R.drawable.ic_dialog_info);
 
            builder.setNeutralButton("OK"new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    ActivityCompat.requestPermissions(MainActivity.this, results, PERMISSION_REQUEST_CONTACTS);
                }
            });
 
            AlertDialog dialog = builder.create();
            dialog.show();
        }
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CONTACTS: {
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        Toast.makeText(this, permissions[i] + " permission granted.", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(this, permissions[i] + " permission denied.", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }
 
    private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss").format(new Date());
        String imageFileName = "IMAGE_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        // If you saved your photo to the directory provided by getExternalFilesDir(),
        // the media scanner cannot access the files because they are private to your app.
        File image = File.createTempFile(imageFileName, ".jpg", storageDir);
        currentPhotoPath = image.getAbsolutePath();
 
        return image;
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
 
        if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
            Bitmap originalBitmap = BitmapFactory.decodeFile(currentPhotoPath);
 
            int scaleFactor = Math.max(originalBitmap.getWidth()/imageView.getWidth(), originalBitmap.getHeight()/imageView.getHeight());
            if (scaleFactor < 1)
                scaleFactor = 1;
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, originalBitmap.getWidth()/scaleFactor,
                    originalBitmap.getHeight()/scaleFactor, true);
 
            Matrix m = new Matrix();
            m.postRotate(90);
            Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 00, scaledBitmap.getWidth(), scaledBitmap.getHeight(), m, true);
 
            imageView.setImageBitmap(rotatedBitmap);
        }
    }
}




Run the app and click CAMERA button.


Take a picture.


The displayed picture is rotated 90 degrees in AVD but is upright in the actual device.


Actual device.


※ Reference:

Android Developers


반응형
Posted by J-sean
: