jump to navigation

Code cài đặt giải thuật PCA – Code PCA 11/08/2013

Posted by hnb1988 in Tìm hiểu & chia sẽ.
Tags: , , , ,
2 comments
Gửi các bạn,
Sau một thời gian dài lúc trước post bài viết tổng quan nhận dạng mặt người
Rất vui khi có rất nhiều bạn quan tâm tới về đề tài này. Và có nhiều bạn hỏi về code cài đặt.
Code này mình tìm hiểu cũng qua các link trên mạng, nhưng sợ bị mất mình mang về đây. Các bạn tham khảo bên dưới.
Trang tham khảo code link gốc (Nếu vẫn còn tồn tại, không thì xem code phía dưới nhé  ^^ ).
Cài đặt giải thuật PCA:

http://c.pastebin.com/z7YmnPLf

OpenCV: Finding Faces
http://www.cognotics.com/opencv/servo_2007_series/part_2/index.html

// eigenface.c, by Robin Hewitt, 2007
//
// Example program showing how to implement eigenface with OpenCV
// Usage:
//
// First, you need some face images. I used the ORL face database.
// You can download it for free at
//    www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html
//
// List the training and test face images you want to use in the
// input files train.txt and test.txt. (Example input files are provided
// in the download.) To use these input files exactly as provided, unzip
// the ORL face database, and place train.txt, test.txt, and eigenface.exe
// at the root of the unzipped database.
//
// To run the learning phase of eigenface, enter
//    eigenface train
// at the command prompt. To run the recognition phase, enter
//    eigenface test
#include <stdio.h>
#include <string.h>
#include “cv.h”
#include “cvaux.h”
#include “highgui.h”
//// Global variables
IplImage ** faceImgArr        = 0; // array of face images
CvMat    *  personNumTruthMat = 0; // array of person numbers
int nTrainFaces               = 0; // the number of training images
int nEigens                   = 0; // the number of eigenvalues
IplImage * pAvgTrainImg       = 0; // the average image
IplImage ** eigenVectArr      = 0; // eigenvectors
CvMat * eigenValMat           = 0; // eigenvalues
CvMat * projectedTrainFaceMat = 0; // projected training faces
//// Function prototypes
void learn();
void recognize();
void doPCA();
void storeTrainingData();
int  loadTrainingData(CvMat ** pTrainPersonNumMat);
int  findNearestNeighbor(float * projectedTestFace);
int  loadFaceImgArray(char * filename);
void printUsage();
//////////////////////////////////
// main()
//
void main( int argc, char** argv )
{
        // validate that an input was specified
        if( argc != 2 )
        {
                printUsage();
                return;
        }
        if( !strcmp(argv[1], “train”) ) learn();
        else if( !strcmp(argv[1], “test”) ) recognize();
        else
        {
                printf(“Unknown command: %s\n”, argv[1]);
                printUsage();
        }
}
//////////////////////////////////
// learn()
//
void learn()
{
        int i, offset;
        // load training data
        nTrainFaces = loadFaceImgArray(“train.txt”);
        if( nTrainFaces < 2 )
        {
                fprintf(stderr,
                        “Need 2 or more training faces\n”
                        “Input file contains only %d\n”, nTrainFaces);
                return;
        }
        // do PCA on the training faces
        doPCA();
        // project the training images onto the PCA subspace
        projectedTrainFaceMat = cvCreateMat( nTrainFaces, nEigens, CV_32FC1 );
        offset = projectedTrainFaceMat->step / sizeof(float);
        for(i=0; i<nTrainFaces; i++)
        {
                //int offset = i * nEigens;
                cvEigenDecomposite(
                        faceImgArr[i],
                        nEigens,
                        eigenVectArr,
                        0, 0,
                        pAvgTrainImg,
                        //projectedTrainFaceMat->data.fl + i*nEigens);
                        projectedTrainFaceMat->data.fl + i*offset);
        }
        // store the recognition data as an xml file
        storeTrainingData();
}
//////////////////////////////////
// recognize()
//
void recognize()
{
        int i, nTestFaces  = 0;         // the number of test images
        CvMat * trainPersonNumMat = 0;  // the person numbers during training
        float * projectedTestFace = 0;
        // load test images and ground truth for person number
        nTestFaces = loadFaceImgArray(“test.txt”);
        printf(“%d test faces loaded\n”, nTestFaces);
        // load the saved training data
        if( !loadTrainingData( &trainPersonNumMat ) ) return;
        // project the test images onto the PCA subspace
        projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
        for(i=0; i<nTestFaces; i++)
        {
                int iNearest, nearest, truth;
                // project the test image onto the PCA subspace
                cvEigenDecomposite(
                        faceImgArr[i],
                        nEigens,
                        eigenVectArr,
                        0, 0,
                        pAvgTrainImg,
                        projectedTestFace);
                iNearest = findNearestNeighbor(projectedTestFace);
                truth    = personNumTruthMat->data.i[i];
                nearest  = trainPersonNumMat->data.i[iNearest];
                printf(“nearest = %d, Truth = %d\n”, nearest, truth);
        }
}
//////////////////////////////////
// loadTrainingData()
//
int loadTrainingData(CvMat ** pTrainPersonNumMat)
{
        CvFileStorage * fileStorage;
        int i;
        // create a file-storage interface
        fileStorage = cvOpenFileStorage( “facedata.xml”, 0, CV_STORAGE_READ );
        if( !fileStorage )
        {
                fprintf(stderr, “Can’t open facedata.xml\n”);
                return 0;
        }
        nEigens = cvReadIntByName(fileStorage, 0, “nEigens”, 0);
        nTrainFaces = cvReadIntByName(fileStorage, 0, “nTrainFaces”, 0);
        *pTrainPersonNumMat = (CvMat *)cvReadByName(fileStorage, 0, “trainPersonNumMat”, 0);
        eigenValMat  = (CvMat *)cvReadByName(fileStorage, 0, “eigenValMat”, 0);
        projectedTrainFaceMat = (CvMat *)cvReadByName(fileStorage, 0, “projectedTrainFaceMat”, 0);
        pAvgTrainImg = (IplImage *)cvReadByName(fileStorage, 0, “avgTrainImg”, 0);
        eigenVectArr = (IplImage **)cvAlloc(nTrainFaces*sizeof(IplImage *));
        for(i=0; i<nEigens; i++)
        {
                char varname[200];
                sprintf( varname, “eigenVect_%d”, i );
                eigenVectArr[i] = (IplImage *)cvReadByName(fileStorage, 0, varname, 0);
        }
        // release the file-storage interface
        cvReleaseFileStorage( &fileStorage );
        return 1;
}
//////////////////////////////////
// storeTrainingData()
//
void storeTrainingData()
{
        CvFileStorage * fileStorage;
        int i;
        // create a file-storage interface
        fileStorage = cvOpenFileStorage( “facedata.xml”, 0, CV_STORAGE_WRITE );
        // store all the data
        cvWriteInt( fileStorage, “nEigens”, nEigens );
        cvWriteInt( fileStorage, “nTrainFaces”, nTrainFaces );
        cvWrite(fileStorage, “trainPersonNumMat”, personNumTruthMat, cvAttrList(0,0));
        cvWrite(fileStorage, “eigenValMat”, eigenValMat, cvAttrList(0,0));
        cvWrite(fileStorage, “projectedTrainFaceMat”, projectedTrainFaceMat, cvAttrList(0,0));
        cvWrite(fileStorage, “avgTrainImg”, pAvgTrainImg, cvAttrList(0,0));
        for(i=0; i<nEigens; i++)
        {
                char varname[200];
                sprintf( varname, “eigenVect_%d”, i );
                cvWrite(fileStorage, varname, eigenVectArr[i], cvAttrList(0,0));
        }
        // release the file-storage interface
        cvReleaseFileStorage( &fileStorage );
}
//////////////////////////////////
// findNearestNeighbor()
//
int findNearestNeighbor(float * projectedTestFace)
{
        //double leastDistSq = 1e12;
        double leastDistSq = DBL_MAX;
        int i, iTrain, iNearest = 0;
        for(iTrain=0; iTrain<nTrainFaces; iTrain++)
        {
                double distSq=0;
                for(i=0; i<nEigens; i++)
                {
                        float d_i =
                                projectedTestFace[i] -
                                projectedTrainFaceMat->data.fl[iTrain*nEigens + i];
                        //distSq += d_i*d_i / eigenValMat->data.fl[i];  // Mahalanobis
                        distSq += d_i*d_i; // Euclidean
                }
                if(distSq < leastDistSq)
                {
                        leastDistSq = distSq;
                        iNearest = iTrain;
                }
        }
        return iNearest;
}
//////////////////////////////////
// doPCA()
//
void doPCA()
{
        int i;
        CvTermCriteria calcLimit;
        CvSize faceImgSize;
        // set the number of eigenvalues to use
        nEigens = nTrainFaces-1;
        // allocate the eigenvector images
        faceImgSize.width  = faceImgArr[0]->width;
        faceImgSize.height = faceImgArr[0]->height;
        eigenVectArr = (IplImage**)cvAlloc(sizeof(IplImage*) * nEigens);
        for(i=0; i<nEigens; i++)
                eigenVectArr[i] = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
        // allocate the eigenvalue array
        eigenValMat = cvCreateMat( 1, nEigens, CV_32FC1 );
        // allocate the averaged image
        pAvgTrainImg = cvCreateImage(faceImgSize, IPL_DEPTH_32F, 1);
        // set the PCA termination criterion
        calcLimit = cvTermCriteria( CV_TERMCRIT_ITER, nEigens, 1);
        // compute average image, eigenvalues, and eigenvectors
        cvCalcEigenObjects(
                nTrainFaces,
                (void*)faceImgArr,
                (void*)eigenVectArr,
                CV_EIGOBJ_NO_CALLBACK,
                0,
                0,
                &calcLimit,
                pAvgTrainImg,
                eigenValMat->data.fl);
        cvNormalize(eigenValMat, eigenValMat, 1, 0, CV_L1, 0);
}
//////////////////////////////////
// loadFaceImgArray()
//
int loadFaceImgArray(char * filename)
{
        FILE * imgListFile = 0;
        char imgFilename[512];
        int iFace, nFaces=0;
        // open the input file
        if( !(imgListFile = fopen(filename, “r”)) )
        {
                fprintf(stderr, “Can\’t open file %s\n”, filename);
                return 0;
        }
        // count the number of faces
        while( fgets(imgFilename, 512, imgListFile) ) ++nFaces;
        rewind(imgListFile);
        // allocate the face-image array and person number matrix
        faceImgArr        = (IplImage **)cvAlloc( nFaces*sizeof(IplImage *) );
        personNumTruthMat = cvCreateMat( 1, nFaces, CV_32SC1 );
        // store the face images in an array
        for(iFace=0; iFace<nFaces; iFace++)
        {
                // read person number and name of image file
                fscanf(imgListFile,
                        “%d %s”, personNumTruthMat->data.i+iFace, imgFilename);
                // load the face image
                faceImgArr[iFace] = cvLoadImage(imgFilename, CV_LOAD_IMAGE_GRAYSCALE);
                if( !faceImgArr[iFace] )
                {
                        fprintf(stderr, “Can\’t load image from %s\n”, imgFilename);
                        return 0;
                }
        }
        fclose(imgListFile);
        return nFaces;
}
//////////////////////////////////
// printUsage()
//
void printUsage()
{
        printf(“Usage: eigenface <command>\n”,
               ”  Valid commands are\n”
               ”    train\n”
               ”    test\n”);
}

Tìm hiểu PhoneGap – Tạo ứng dụng đa hệ trên mobile 23/05/2012

Posted by hnb1988 in android, Android Development, android, programming, Mobile Development, Thông tin công nghệ.
Tags: , , ,
add a comment

Hôm qua nay mình có tìm hiểu sơ một về một công nghệ viết ứng dụng trên mobile. Có thể tạo ứng theo kiểu có thể chạy trên nhiều hệ điều hành mobile khác  nhau. Gọi là Hybird app.

PhoneGap

PhoneGap

1.Tại sao lại sinh ra ứng dụng Hybird app?

Việc các thiết bị mobile ngày càng phát triển dẫn đến những khó khăn trong lập trình các ứng dụng bên trong nó:

  • Quá nhiều hệ điều hành nhiều nền tảng khác nhau.
  • Cần nhiều team để làm việc trên những hệ điều hành, nền tảng đó.
  • Với mỗi lĩnh vực cần chuyên gia có kinh nghiệp trên lĩnh vực đó.
  • Với mỗi nền tảng thì trong từng phiên bản có sự phân mảng khác nhau. Ví dụ với android tính năng này support trên android 2.2 nhưng ver < 2.2 không support….
  • Nhiều môi trường làm việc khác nhau (Window, Mac,..) Tools làm việc…

Xuất hiện các framework sử dụng html, css, js để viết các ứng dụng web mà có thể chạy trên nhiều nền tảng di động khác nhau như PhoneGap, Titanium,…. Trong đó phổ biến nhất là PhoneGap

2.PhoneGap

  • PhoneGap ra đời dựa trên công nghệ web để xây dựng các ứng dụng đi động
  • PhoneGap sử dụng HTML,CSS, và Javascript và xây dựng một bộ các API bằng java script, chương trình thiết kế giao diện bằng HTML, lập trình logic bằng javascript và chạy trong môi trường Web của thiết bị, thông qua PhoneGrap javascipt API thì ứng dụng có thể truy cập được vào những tính năng gốc của máy điện thoại.
  • Người lập trình PhoneGap phát triển chương trình mà không phụ thuộc nhiều vào ngôn ngữ của các Platform Iphone, BB,Symbian. Ứng dụng được phát triển trên IDE của platform ví dụ Iphone dùng Xcode và gói thư viện, BB xài eclipse…
Kiến trúc tổng quan Ponegap

Kiến trúc tổng quan Ponegap

Các tính năng quan trọng của PhoneGap

PhoneGap hỗ trợ truy xuất hầu hết các API của thiết bị như API camera, File, Lưu trữ SQL Lite, Media, GeoLocation…

Các API PhoneGap hỗ trợ

Các API PhoneGap hỗ trợ

Một số tính năng hạn chế của PhoneGap

Một số tính năng chung khác mà phonegap hỗ trợ và hạn chế

Một số tính năng chung khác mà phonegap hỗ trợ và hạn chế

3.Ưu điểm và hạn chế khi phát triển phonegap

Các ưu điểm

  • Một opensource free
  • Hỗ trợ trên nhiều platform iOS, Android, Window mobile, BlackBery, Symbian, webOS, bada à phát triển 1 ứng dụng có thể chạy trên nhiều nền tảng khác nhau, không cần bỏ nhiều resource riêng cho từng nền tảng ứng dụng; đồng nhất giao diện ứng dụng trên các nền tảng khác nhau.
  • Sử dụng javaScript/HTML có thể gọi tới các API native code C,C++, Java
  • Hỗ trợ gần như hầu hết tất cả các thư viện gọi tới hệ điều hành phone. (Định vị, Camera, truy cập file, database…)

 Khó khăn

  • Khó hoạt động trên các mobile browser cũ vì không hỗ trợ javascript và tốc độ chậm
  • Việc quản lý các tài nguyên sâu của thiết bị không thực hiện được như: quản lý các tiến trình(đồng bộ, bất đồng bộ), khả năng đồ họa hạn chế (3D).
  • Layout ứng dụng sẻ không phù hợp khi qua các màn hình thiết bị có độ phân giải khác nhau, và tùy thuộc vào độ hỗ trợ của trình HTML của thiết bị. vd các apps cho android trên các thiết bị khác nhau thì sẽ không rõ nét vì trên androids hỗ trợ các bộ icon cho các độ phân giải khác nhau nên rõ nét hơn.
  • Các bộ nhập liệu trên từng thiết bị không điều khiển được như: keypad, track ball, tapping,rocker …
  • Khó trong việc phát triển vì debug khó khăn
  • Tài liệu khá ít, Phonegap đang trên đà hoàn thiện vì thế nguy cơ tiềm ẩn khi phát triển ứng dụng bị stuck là điều có thể xảy ra.

4.Kết luận

  • Phonegap thích hợp để phát triển các ứng dụng không cần đòi hỏi giao diện quá cao, quá nét như các native app (vd apps quản lý bán hàng, quản lý thông tin nhân sự….)
  • Các apps thiên về xử lý native nhiều, đòi hỏi giao diện, mức độ tương tác, đa phương tiện cao và sắc nét trên từng nền tảng hơn thì không nên dùng phonegap như apps xử lý đồ họa(3D)
  • Tuy  PhoneGap có thể làm rất tốt việc tạo ra hầu hết ứng dụng, nhưng chúng không thể làm cho JavaScript chạy hiệu quả như chương trình C. Phiên bản web làm việc ổn, nhưng ứng dụng viết riêng cho thiết bị đem đến cho người dùng trải nghiệm tốt hơn mà ứng dụng web hiện nay không thể đạt được.

Bài viết chỉ mới là tìm hiểu sơ bộ về PhoneGap cũng như các công nghệ Hybird khác. Bài viết sau mình sẽ bắt đầu đi rõ hơn về kiến trúc, các API support của PhoneGap.
PhoneGap support nhiều OS khác nhau, nhưng mình sẽ chọn Android để làm việc chính với PhoneGap. Và sẽ nói cách setup môi trường làm việc, demo…

———————————————————

bloghnb

Tham khảo thêm: http://phonegap.com/

Ebook: Beginning Phonegap

Dự báo vui về năm rồng Mậu Thìn (1988) 27/01/2012

Posted by hnb1988 in Góc cá nhân.
Tags: , , , ,
add a comment

Trước giờ ít quan tâm tới những dự đoán, dự báo như thế này. :). Nhưng lỡ đọc qua để đây thử kiểm nghiệm một năm tới cho vui.

Với tôi một năm tới mục tiêu của tôi là khắc phục, làm chủ được bản thân (không nóng nảy,  không vội vàng có thể sống chậm một tí..) và làm một việc mà 4 năm trước tôi đã từng làm và làm tốt (cái này bí mật một tí tuy không có gì ghê gớm :) )

Mậu Thìn (1988), Mệnh Đại Lâm Mộc (cây ở rừng lớn)

Năm rồng

Năm rồng

Năm nay, Thiên can Mậu gặp Nhâm (Dương Thổ gặp Dương Thuỷ). Theo Ngũ hành Thổ khắc Thuỷ (khắc xuất). Người tuổi Mậu Thìn năm nay luôn là người chiến thắng, thành đạt, toại nguyện. Tuy nhiên, do là “khắc” nên phải chiến đấu giành giật mới có. Cần tránh tư tưởng “há miệng chờ sung”.

Nam: Vốn là người tự tin, khôn ngoan và nhiều tham vọng, năm nay là năm thuận, nên cố gắng gánh vác việc lớn ắt sẽ thắng lợi, giao việc lớn để thử thách. Về mặt tài chính sẽ gặt hái được nhiều nhưng trang trải cũng lớn nên “của ăn của để” chẳng được là bao. Năm dễ đi đến hôn nhân nếu không cũng có bạn gái. Nam Mậu Thìn hợp với nữ Kỷ Tỵ (1989), Quý Dậu (1993), Đinh Mão (1987). Khắc với nữ tuổi Mậu Thìn (1988), Nhâm Thân (1992), Tân Mùi (1991).

Nữ: Là người cương nghị, thẳng thắn nhưng hơi nóng nảy và “khô”. Năm nay là cơ hội về nhiều mặt, nên phải bớt nóng và ít “khô” hơn để hoà nhập, nắm bắt cơ hội thì kết quả mỹ mãn trên mọi lĩnh vực luôn chờ đón bạn. Ngoài sự nghiệp, ở tuổi này nghĩ đến chọn bạn đời và xây dựng mái ấm gia đình là điều phải tính đến. Tuổi Mậu Thìn nên tìm bạn trăm năm với nam tuổi Kỷ Tỵ (1989), Đinh Mão (1987), Ất Sửu (1985). Khắc với tuổi Bính Dần (1986), Canh Thân (1980), Tân Mùi (1991).Box:Dự báo theo tử vi thực chất là giải bài toán hàm số với nhiều tham số (biến số) đó là giới tính, giờ, ngày, tháng, năm sinh theo hệ Can chi (Hệ nhị phân). Để có được đáp số (dự đoán) chính xác không phải dễ.

Tuy nhiên, đây là cách lý giải, quy nạp có logic trật tự và mang tính hướng thiện. Bởi vậy không nên tin theo kiểu “định mệnh” không thể thay đổi mà nên hiểu đó chỉ là xu hướng của cuộc đời giúp ta biết sở trường để phát huy, sở đoản để khắc phục. Đã là dự đoán ắt có đúng, có sai đừng quá tin hay quá ngờ vực là hai thái cực “thái quá và bất cập”. Hãy cứ trải nghiệm để rút ra những điều bổ ích là điều cần thiết.

Trích từ báo: baoquangngai.com.vn

Có nên mua và sử dụng Smartphone hay không? 03/11/2011

Posted by hnb1988 in android, Góc cá nhân, iphone.
Tags: , , ,
add a comment

Đây cũng là câu hỏi của nhiều người khi sắp mua hay muốn sử dụng một chiếc điện thoại thông minh. Và tôi trước kia cũng vậy.

Smartphone

Smartphone

Với đa số nhiều người thì nếu có điều kiện, tiền bạc thoải mái một tí thì sở hữu một chiếc điện thoại thông minh là một nhu cầu. Cũng có một vài trường hợp thì có vài ý nghĩ khác cho rằng việc dùng điện thoại thông minh không có gì khác biệt cho lắm, suy cho cùng thì cũng là nghe gọi nhắn tin… :)

Có thể có vài nhận xét trái chiều nhau nhưng điều nhận thấy rằng sau khi dùng một chiếc điện thoại thông minh thì hầu như ai cũng thích dùng nó cả, nó có nhiều tiện ích hấp dẫn người dùng và hỗ trợ nhiều loại người dùng.

Hầu như ai cũng thích dùng, vậy thì dùng nó mang lại lợi ích gì ?. Nhiều thứ, có thể nói như vậy và tùy vào đối tượng người dùng. Với đa số người thì điện thoại thông minh mang lại người ta nhiều điều thú vị với sự giải trí tuyệt vời (xem phim, nghe nhạc, game,…), những người muốn sử dụng điện thoại thông minh cho nhu cầu học thì nó có thể cài thêm nhiều tiện ích hỗ trợ như từ điển, các phần mềm học ngoại ngữ,… Với những người dùng cho công việc thì việc lưu trữ lịch họp, nhắc  bạn công việc, việc check mail trở nên dễ dàng hơn bao giờ…

Còn những ai thích công nghệ thì lựa chọn điện thoại thông minh để khám phá thì một điều tốt thôi, có thể cho bạn nhiều ý tưởng để xây dựng những ứng dụng tích hợp vào nó. Với tôi cũng vậy đang làm về android, sử dụng một chiếc chạy android tiếp xúc với nhiều phần mềm chạy trên đó cho tôi nhiều cảm nhận về sự tốt thuận tiện hơn khi xây dựng ứng dụng trong khi mình làm…

Đó là một số thuận tiện, ngoài ra có quá nhiều tiện ích bạn không thể biết đên khi bạn chưa sử dụng tới nó. Ví dụ tôi có vài người bạn ở nước ngoài lúc trước muốn nói chuyện thì chỉ biết tới yahoo để chat, email hay cao hơn dùng skype để nói chuyện. Nhưng dùng điện thoại chạy android tôi có thể cài Viber một phần mềm chuyên gọi điện trực tuyến thông qua internet. Tài khoản chính là số điện thoại của bạn luôn… làm cho bạn cảm giác như đang nói chuyện bình thường vậy… :)

Có thể cùng một chức năng như nhau nhưng điện thoại thông minh hành xử khác điện thoại phổ thông làm cho ta sẽ thích chúng.

Do vậy tôi nghĩ nếu có điều kiện thì việc bạn phân vân có nên mua và sử dụng một chiếc smartphone hay không thì tôi nghĩ không có gì phải phân vân. Chỉ là phân vân nên mua con như thế nào để vừa với kinh phí của mình. :)

Sử dụng ExifInterface, và cách giải quyết vấn đề khi sử dụng với android 1.6 09/09/2011

Posted by hnb1988 in Android Development.
Tags: , , , , ,
add a comment

ExifInterface là một lớp hỗ trợ xử lý một vài thuộc tính trong việc xử hình ảnh. Nhưng nó chỉ support trên android 2.2 trở lên (API Level 5)

Ví dụ trên android, khi bạn chụp một tấm hình từ camera và load lên GUI, ở đa số phone bạn chụp hình đứng nhưng khi lưu ảnh được lưu dưới dạng ngang. Khi load ảnh lên view thì ảnh cũng bị quay ngang. Do dó ExifInterface giúp bạn kiểm tra được ảnh ban đầu được chụp như thế nào,…

Với ExifInterface bạn có thể dễ dàng kiểm tra:

ExifInterface exif = new ExifInterface(SourceFileName); //Since API Level 5

String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Tùy ảnh được chụp theo hướng nào, kết quả exifOrientation cho bạn giá trị khác nhau.

Nhưng vấn đề xảy ra nếu bạn dùng android 1.6 chẳng hạn thì bạn giải quyết làm sao khi không support được lớp ExifInterface 

Không phải lo lắng, có một thư viện khác giúp bạn được điều này. Thư viện metadata extraction library by Drew Noakes.
drewnoakes.com – jpeg exif / iptc metadata extraction in java

Sau khi bạn down thư viện về, bạn cần custom lại một tí để không bị lỗi. Nếu hơi khó khăn bạn có thể download link bên dưới. Mình đã custom lại để chạy được và rút gọn những phần không phù hợp để nhẹ hơn.

Khi sử dụng, ví dụ cũng như ví dụ trên với thư viện này bạn có thể làm như sau:

Metadata metadata;

metadata = JpegMetadataReader.read

Metadata(new File(filePath));

Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);

if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {

int rotated = exifDirectory .getInt(ExifDirectory.TAG_ORIENTATION);

}

Còn vấn đề gì, bạn có thể post lên để cùng thảo luận.
Các bạn có thể download link thư viện bên dưới:
khoinguonit.com – metadata.jar

Draw 9-patch Tutorial – Sử dụng nine patch 31/08/2011

Posted by hnb1988 in Android Development.
Tags: , , , , , , ,
add a comment

Tool Draw 9-patch cho phép bạn tạo ảnh 9 patch dễ dàng hơn với WYSIWYG 

Tạo ảnh 9 -patch không phải quá khó, nhưng để sử dụng tools này có hiệu quả, vào tùy biến áp dụng được cho nhiều hình thì cũng có nhiều điều chúng ta cần quan tâm.

1. Sử dụng cơ bản:

Chúng ta cần một ảnh PNG

Mở tool draw9patch trong thư mục SDK /tools

Rồi bạn chỉ việc kéo thả ảnh ( mở ảnh png) để tiếp tục chỉnh sửa.

Bạn vẽ những pixel ở những vùng trên ảnh mà bạn muốn nơi nó ảnh được co giãn khi phóng to thu nhỏ mà không làm vỡ ảnh ở những chi tiết khác.

Sau khi vẽ xong bạn lưu lại với format 9.png

Chú ý: Khi bạn mở một ảnh thì chương trình xuất hiện thêm đường viền 1 pixel để bạn chấm những điểm mà bạn muốn ảnh của bạn co giản không bị vỡ.

draw9patch

draw9patch

 

2. Một số option trong tool:

  • Zoom: Zoom vùng ảnh bạn đang chỉnh sửa vẽ 9.patch.
  • Patch scale: scale vùng ảnh để xem kết quả pre-view của ảnh sau khi chấm 9.patch.
  • Show lock: lock vùng ảnh đang chỉnh sửa khi move chuột qua vùng ảnh.
  • Show patches: Hiển thị vùng ảnh stretchable.
  • Show content: Highlight vùng ảnh hiển thị  kết quả (purple is the area in which content is allowed).
  • Show bad patches: Hiển thị vùng ảnh được chọn để scale.
Optional controls include
Optional controls include
3.Vẽ nâng cao
Vẽ button
Dưới đây là hỉnh ảnh của một button đơn giản, để 9patch cho button thì chúng ta có thể để ý là không cho co giãn những góc của button. Như vậy ta có thể chọn 9.patch như sau.
9patch button

9patch button

Vẽ Spiner button
Với spiner chúng ta không muốn vỡ phần hình dấu mũi tên lựa chọn, thì chúng ta chỉ có thể cho giãn phần giữa của spiner. Có thể vẽ như sau.
9patch spiner button
9patch spiner button
Vẽ Search Edittext
Tương tự như spiner, chúng ta chỉ có thể co giãn ở phần giữa,
9patch search edittext
9patch search edittext
Nếu có hình bạn chỉ muốn co giãn phần ngoài, giữ nội dung ở giữa thì bạn chỉ chọn những pixel ở bên ngoài để co giãn phần ngoài.
test_9patch_patched

test_9patch_patched

Kết quả thu được.
Kết quả
Kết quả
Sử dụng thuần thục cách vẽ 9patch các bạn sẽ có thể custom dễ dàng hơn những control trong android. Chúc các bạn thành công!
————————————————————-
bloghnb
Tham khảo thêm: http://android10.org, higherpass.com

Custom một control trong android? 28/08/2011

Posted by hnb1988 in Android Development.
Tags: , , ,
add a comment
Demo Custom

Demo Custom

Control trong Android có đủ để chúng ta viết ứng dụng không.?

Câu trả lời đa số có thể trả lời “Đủ”.

Vậy tại sao chúng ta lại custom nhưng control trong android.?

Ok, Dùng control trong android cung cấp hoàn toàn cho ta một ứng dụng tốt, nhưng để ứng dụng của ta khác với người khác, cùng một ứng dụng quản lý danh bạ chẳng hạn. Nếu chúng ta có những ý tưởng mới lạ từ việc những editext nhập liệu cách điệu hơn, những dialog lạ lẫm hơn,.. điều đó làm cho ứng dụng của bạn nỗi bậc hơn… gây chú ý tới người dùng hơn.

Một điều nữa, chúng ta muốn ứng dụng của ta có GUI thống nhất trên tất cả các phiên bản, các dòng điện thoại thì custom là một lựa chọn tốt cho bạn. Vì những control trong android có giao diện có thể khác nhau từ những dòng điện thoại, phiên bản android….

Tạo những custom control cần gì.

Trước hết có lẽ chúng cũng phải sử dụng được những control của android để biết chúng ta cần gì, thiếu gì từ những control chuẩn trong android. Từ đó cho ta những custom tốt hơn, phù hợp với nghiệp vụ ứng dụng của ta hơn…

Chúng ta cần biết cách custom các shape (đường viền, bo góc, gradient,…), selector(các hiệu ứng khi chọn, click,…), sử dụng 9.path để vẽ tối ưu hơn…

Các bài viết sau mình sẽ giới thiệu cách tạo một vài custom đơn giản để các bạn nào mới tiếp cận có thể có thêm những tùy biến tốt hơn cho ứng dụng của mình.

 

 

———————————————-

bloghnb

Hướng dẫn get contact list trên nhiều phiên bản OS khác nhau trên cùng ứng dụng 17/06/2011

Posted by hnb1988 in Android Development.
Tags: , , , , , ,
add a comment

Hôm trước có đề cập tới việc lấy danh sách liên lạc (contact list trên OS 1.6). Vấn đề lấy danh bạ điện thoại thì khá đơn giản. Ở đây chỉ có một vấn đề nhỏ tí là thư viện hỗ trợ việc lấy danh bạ và thao tác trên nó khác nhau giữa OS 1.6 và sau này.

Lấy danh bạ từ từ OS 1.6 về sau

Lấy danh bạ từ từ OS 1.6 về sau

Hôm nay gửi các bạn một cách lấy danh bạ trên cả phiên bản OS 1.6 và OS sau này trên cùng một ứng dụng.

Ý tưởng, đầu tiên bạn tìm cách lấy được phiên bản sdk của bạn. Sau đó tùy từng sdk mà bạn lựa chọn gói thư viện phù hợp. Sau bước này thì bạn thao tác bình thường.

//Dinh nghia lua chon thu vien su dung get contactlist
	static {
		int sdk = new Integer(Build.VERSION.SDK).intValue();

		if (sdk >= 5) {
			try {
				Class clazz = Class
						.forName("android.provider.ContactsContract$Contacts");

				CONTENT_URI = (Uri) clazz.getField("CONTENT_URI").get(clazz);
			} catch (Throwable t) {
				Log.e("PickDemo", "Loi khi thuc hien chuyen doi CONTENT_URI", t);
			}
		} else {
			CONTENT_URI = Contacts.People.CONTENT_URI;
		}
	}
Lấy danh bạ điện thoại từ OS 1.6 về sau

Lấy danh bạ điện thoại từ OS 1.6 về sau

 

Bạn có thể download mã nguồn tại http://www.mediafire.com/file/jrw8fsqr9clmyo2/khoinguonit.com%20-%20PickContact.rar

Pass: khoinguonit.com

 

 

—————————————–

bloghnb – IT & Life

Học cách để gặp may mắn 29/05/2011

Posted by hnb1988 in Góc cuộc sống.
Tags: , ,
1 comment so far

Lòng vòng trên web, may mắn gặp được một bài viết khá hay và ý nghĩa.. và lưu lại ở blog mình để có dịp đọc tiếp…

Ngay câu đầu tiên blog mình cũng phải tập học làm người gặp may mắn.. :) Dưới đây là bài viết đó.

Cỏ 4 lá - một biểu tượng của sự may mắn (ảnh: Internet)

Cỏ 4 lá - một biểu tượng của sự may mắn (ảnh: Internet)

Trên thế giới có 3 loại người: người may mắn, người xui xẻo và bình thường. Ai cũng muốn là người may mắn, nhưng không phải ai cũng được như thế. Nhưng nếu biết cách, bạn sẽ là người may mắn.

GS Richard Wiseman, ĐH Hertfordshire (Anh) đã làm một cuộc nghiên cứu cực kì công phu trên 400 người từ 18-84 tuổi trong suốt hơn 10 năm, để tìm hiểu về quy luật may mắn của con người.

Qua nghiên cứu này, ông đã rút ra được khá nhiều điều lý thú và hữu ích cho tất cả mọi người muốn mình trở nên may mắn hơn.

Cuộc sống là một trò chơi tìm kiếm

Trong một cuộc thí nghiệm, GS Wiseman đưa cho người may mắn và xui xẻo 2 tờ báo và hỏi họ: “Hãy tìm cho tôi có bao nhiêu tấm hình trong tờ báo này?” Người xui xẻo mất 2 phút, trong khi người may mắn chỉ mất có vài giây. Tại sao lại như vậy?

Vì ở ngay trang 2 của tờ báo có một dòng chú thích: “Đừng tìm nữa, tờ báo này có 43 tấm hình”. Cuộc thí nghiệm được làm lại nhiều lần và người xui xẻo chẳng bao giờ nhìn ra dòng chữ ấy.

Bài học rút ra là: người xui xẻo đã bỏ lỡ cơ hội vì họ quá bận rộn, quá tập trung vào những gì đang làm. Trong khi đó, người may mắn luôn biết nhận ra những gì khác biệt hơn là những gì họ tìm kiếm.

May mắn thường gõ cửa những người luôn sáng tạo và luôn biết cách làm mới mình, làm mới môi trường xung quanh mình.

Nếu ví sự may mắn là trái táo và môi trường quanh bạn là một vườn táo. Hàng ngày, bạn chỉ cứ hái mãi ở một vườn, càng ngày bạn sẽ càng khó tìm thấy, vì táo ít đi từng ngày.

Nhưng nếu bạn sang một vườn táo mới, xác suất hái được táo của bạn sẽ tăng lên đột ngột. Đó chính là sự may mắn!

Biết là mình may mắn

Sở dĩ GS Wiseman chia ra làm hai loại người: may mắn và không may mắn vì… chính họ đã tự nhận mình là như vậy. Cùng một sự việc, người may mắn và xui xẻo có thể nhìn dưới 2 khía cạnh khác hẳn nhau.

Cũng như một đội tuyển tham dự Olympic vậy, năm nay họ thi đấu chỉ đoạt huy chương đồng, sang năm, họ tập luyện chăm chỉ hơn và rồi đạt huy chương bạc. Nhưng bạn hãy thử đoán xem, lúc nào họ vui hơn?

Khi đoạt huy chương bạc, họ cảm thấy xui xẻo vì chỉ còn một chút nữa thôi là họ có thể làm được điều tốt nhất. Còn khi chỉ đoạt huy chương đồng, họ lại thấy may mắn, vì nếu họ không cố gắng dù chỉ là một chút nữa thôi thì họ đã không có gì cả.

Các nhà nghiên cứu gọi đây là hiện tượng suy nghĩ “phản thực” (counter-factual). Những người may mắn là người biết biến sự xui xẻo thành cảm giác may mắn.

Trong một thí nghiệm khác, GS Wiseman đặt ra trường hợp rằng: một ngày bạn vào nhà băng, thế rồi bất chợt bọn cướp xuất hiện, chúng bắn bừa một viên đạn thế nào lại trúng vào vai bạn. Quan điểm của người xui xẻo là: “Ôi trời, sao tôi xui xẻo đến thế. Đến nhà băng ngày nào không đến, lại đến đúng ngày có cướp viếng, đã thế lại bị tai bay đạn lạc”.

Trong khi đó, quan điểm của người may mắn là: “Ôi may quá! Đạn chỉ trúng vào vai mà không vào đầu mình”!

Chính quan điểm ấy giúp họ có một cuộc sống tràn đầy tự tin và hy vọng. Họ luôn lạc quan ngay cả khi khó khăn nhất.

Luyện để trở thành người may mắn

Học cách gặp may mắn

Học cách gặp may mắn

Mục đích của nghiên cứu này là rút ra những kinh nghiệm và thói quen có thể giúp chúng ta tìm thấy nhiều sự may mắn hơn.

GS Wiseman tổ chức một cuộc trao đổi giữa hai nhóm người. Những người may mắn sẽ nói về cách họ suy nghĩ, cảm nhận về cuộc sống, cách họ tìm kiếm may mắn, phá vỡ các thói quen và giải quyết những xui xẻo.

Những người xui xẻo được giao nhiệm vụ là hãy thay đổi một số thói quen, lối sống. Sau đó chỉ một tháng, những kết quả báo lại thật bất ngờ: 80% số người xui xẻo đã cảm thấy sống tốt hơn, vui vẻ hơn và may mắn hơn.

Piper, một người thuộc nhóm xui xẻo nói: “Tôi đã tự lập ra một số sở thích và thói quen bất chấp những hạn chế của mình. Ví dụ như vào các sáng thứ 7, tôi rất muốn đi câu, vì vướng chuyện học lại thôi.

Nhưng lúc đó, tôi vẫn cứ đi câu bất chấp vẫn còn một đống bài ở nhà. Trong khi câu cá, chúng tôi đã trao đổi cùng nhau về bài luận, tôi đã nhận ra khá nhiều điều lý thú và tôi đã có một bài luận điểm A”.

Alesadra nói: “Tuần trước, tôi thấy có một cái váy rất đẹp, nhưng không mua. Hôm sau tôi quay lại để mua thì người ta đã bán mất. Nếu là trước đây, tôi sẽ thất vọng, buồn rầu mà đi về. Nhưng sau khi đi một vòng, tôi lại tìm được một cái khác đẹp hơn và còn rẻ hơn thế. Thật là may mắn”!

Có lẽ, may mắn hay xui xẻo cũng chỉ là một khái niệm trìu tượng và do quan điểm của mỗi chúng ta. Vậy là bài học rút ra ở đây thật sự chẳng có gì cao siêu cả.

Nếu bạn muốn là người may mắn, hãy tự xếp hạng mình là người “số đỏ”. Hãy luôn suy nghĩ tích cực, rằng những may mắn đến với bạn là do bạn xứng đáng được hưởng, còn những xui xẻo chẳng qua là những thử thách giúp chúng ta cứng cỏi hơn mà thôi.

Hãy nhớ rằng: “Khi một cánh cửa sập lại với bạn, chắc chắn sẽ có 5, 7 cánh cửa khác trải thảm đỏ đón bạn”!

 

Bài viết từ gtdt.vn

Bài nói chuyện của Steve Jobs tại buổi lễ tốt nghiệp đại học Stanford 2005 25/05/2011

Posted by hnb1988 in Góc cuộc sống.
Tags: , ,
add a comment

Đây là một bài nói chuyện của CEO Apple Steve Jobs trong một buổi lễ tốt nghiệp đại học Stanford (2005). Nhiều câu chuyện trải nghiệm thú vị và ý nghĩa từ cuộc đời cảu Steve Jobs… rất đáng để chúng ta học tập.

Steve Jobs' 2005 Stanford Commencement

Steve Jobs' 2005 Stanford Commencement

Phát biểu trong một buổi lễ tốt nghiệp, nhưng Steve Jobs lại chưa tốt nghiệp đại học lần nào… :) nhưng những trải nghiệp của Steve Jobs thật thú vị.

Steve Jobs cho ta 3 câu chuyện, mỗi một câu chuyện có nhiều điều để ta học tập.. từ làm việc cho tới biết quý trọng cuộc sống…

Video cuộc nói chuyện: http://www.youtube.com/watch?v=UF8uR6Z6KLc

Dưới đây là bài nói chuyện của Steve Jobs, lưu lại ở đây lúc nào đọc lại… và ngẫm nghĩ.. :)

‘You’ve got to find what you love,’ Jobs says

This is a prepared text of the Commencement address delivered by Steve Jobs, CEO of Apple Computer and of Pixar Animation Studios, on June 12, 2005.

I am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I’ve ever gotten to a college graduation. Today I want to tell you three stories from my life. That’s it. No big deal. Just three stories.

The first story is about connecting the dots.

I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out?

It started before I was born. My biological mother was a young, unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: “We have an unexpected baby boy; do you want him?” They said: “Of course.” My biological mother later found out that my mother had never graduated from college and that my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would someday go to college.

And 17 years later I did go to college. But I naively chose a college that was almost as expensive as Stanford, and all of my working-class parents’ savings were being spent on my college tuition. After six months, I couldn’t see the value in it. I had no idea what I wanted to do with my life and no idea how college was going to help me figure it out. And here I was spending all of the money my parents had saved their entire life. So I decided to drop out and trust that it would all work out OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the required classes that didn’t interest me, and begin dropping in on the ones that looked interesting.

It wasn’t all romantic. I didn’t have a dorm room, so I slept on the floor in friends’ rooms, I returned coke bottles for the 5¢ deposits to buy food with, and I would walk the 7 miles across town every Sunday night to get one good meal a week at the Hare Krishna temple. I loved it. And much of what I stumbled into by following my curiosity and intuition turned out to be priceless later on. Let me give you one example:

Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every drawer, was beautifully hand calligraphed. Because I had dropped out and didn’t have to take the normal classes, I decided to take a calligraphy class to learn how to do this. I learned about serif and san serif typefaces, about varying the amount of space between different letter combinations, about what makes great typography great. It was beautiful, historical, artistically subtle in a way that science can’t capture, and I found it fascinating.

None of this had even a hope of any practical application in my life. But ten years later, when we were designing the first Macintosh computer, it all came back to me. And we designed it all into the Mac. It was the first computer with beautiful typography. If I had never dropped in on that single course in college, the Mac would have never had multiple typefaces or proportionally spaced fonts. And since Windows just copied the Mac, it’s likely that no personal computer would have them. If I had never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backwards ten years later.

Again, you can’t connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.

My second story is about love and loss.

I was lucky — I found what I loved to do early in life. Woz and I started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a $2 billion company with over 4000 employees. We had just released our finest creation — the Macintosh — a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.

I really didn’t know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down – that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over.

I didn’t see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.

During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I returned to Apple, and the technology we developed at NeXT is at the heart of Apple’s current renaissance. And Laurene and I have a wonderful family together.

I’m pretty sure none of this would have happened if I hadn’t been fired from Apple. It was awful tasting medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don’t lose faith. I’m convinced that the only thing that kept me going was that I loved what I did. You’ve got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven’t found it yet, keep looking. Don’t settle. As with all matters of the heart, you’ll know when you find it. And, like any great relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don’t settle.

My third story is about death.

When I was 17, I read a quote that went something like: “If you live each day as if it was your last, someday you’ll most certainly be right.” It made an impression on me, and since then, for the past 33 years, I have looked in the mirror every morning and asked myself: “If today were the last day of my life, would I want to do what I am about to do today?” And whenever the answer has been “No” for too many days in a row, I know I need to change something.

Remembering that I’ll be dead soon is the most important tool I’ve ever encountered to help me make the big choices in life. Because almost everything — all external expectations, all pride, all fear of embarrassment or failure – these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.

About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn’t even know what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than three to six months. My doctor advised me to go home and get my affairs in order, which is doctor’s code for prepare to die. It means to try to tell your kids everything you thought you’d have the next 10 years to tell them in just a few months. It means to make sure everything is buttoned up so that it will be as easy as possible for your family. It means to say your goodbyes.

I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with surgery. I had the surgery and I’m fine now.

This was the closest I’ve been to facing death, and I hope it’s the closest I get for a few more decades. Having lived through it, I can now say this to you with a bit more certainty than when death was a useful but purely intellectual concept:

No one wants to die. Even people who want to go to heaven don’t want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life’s change agent. It clears out the old to make way for the new. Right now the new is you, but someday not too long from now, you will gradually become the old and be cleared away. Sorry to be so dramatic, but it is quite true.

Your time is limited, so don’t waste it living someone else’s life. Don’t be trapped by dogma — which is living with the results of other people’s thinking. Don’t let the noise of others’ opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.

When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960′s, before personal computers and desktop publishing, so it was all made with typewriters, scissors, and polaroid cameras. It was sort of like Google in paperback form, 35 years before Google came along: it was idealistic, and overflowing with neat tools and great notions.

Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find yourself hitchhiking on if you were so adventurous. Beneath it were the words: “Stay Hungry. Stay Foolish.” It was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished that for myself. And now, as you graduate to begin anew, I wish that for you.

Stay Hungry. Stay Foolish.

Thank you all very much.

————————————————————

Bài viết từ nguồn: http://news.stanford.edu/news/2005/june15/jobs-061505.html

Follow

Get every new post delivered to your Inbox.