screenshot.cpp

来自「Symbian_OS_code 初学Symbian_OS学习代码, 屏幕截图软」· C++ 代码 · 共 739 行 · 第 1/2 页

CPP
739
字号
            TRAPD(err, DoSaveL());
            if (KErrNone != err)
                {
                iScreenShotStatus = EIdle;
                iIsCapturing = EFalse;
                iObserver.OnSaveCompleted(err);
                }
            else
                {
                iObserver.OnCaptureCompleted(KErrNone);
                iScreenShotStatus = EConverting;
                SetActive();
                }
            break;
            }

        // The saving is done.
        case EConverting:
            {
            iObserver.OnSaveCompleted(iStatus.Int());

            // Check whether the user has stopped the capturing or not.
            // If iIsCapturing is EFalse, the user hasn't stopped it.
            if ((iIsCapturing) && (KErrNone == iStatus.Int()))
                {
                switch (iScreenShotData.Mode())
                    {
                    // If the mode is one shot only, then it is in idle state now.
                    case CScreenShotData::EModeOneShot:
                        iScreenShotStatus = EIdle;
                        break;

                    // Otherwise, request another screenshot capture.
                    case CScreenShotData::EMode2Seconds:
                        FireCapture(2 * KOneSecond);
                        break;
                    case CScreenShotData::EMode5Seconds:
                        FireCapture(5 * KOneSecond);
                        break;
                    case CScreenShotData::EMode10Seconds:
                        FireCapture(10 * KOneSecond);
                        break;
                
                    default:
                        User::Invariant();
                    } // switch
                } // if
            else
                {
                iIsCapturing = EFalse;
                iScreenShotStatus = EIdle;
                }
            break;
            }

        default:
            User::Invariant();
        }
    }

// --------------------------------------------------------------------------
// Cancel any outstanding request.
// --------------------------------------------------------------------------
void CScreenShot::DoCancel()
    {
    if (iImageEncoder)
        {
        iImageEncoder->Cancel();
        delete iImageEncoder;
        iImageEncoder = 0;
        }

    iTimer.Cancel();
    iScreenShotStatus = EIdle;
    }

// --------------------------------------------------------------------------
// Captures the screenshot and store it to a buffer.
// --------------------------------------------------------------------------
void CScreenShot::DoCaptureL()
    {
    iOverlay->MakeVisible(ETrue);
    iOverlay->SetRect(TRect(TPoint(0, 0), TSize(1, 1)));
    
    const CWsScreenDevice* screenDevice = iCoeEnv.ScreenDevice();
	
	TPixelsTwipsAndRotation sizeAndRotation;
	screenDevice->GetScreenModeSizeAndRotation(
			screenDevice->CurrentScreenMode(), sizeAndRotation);

    // Creates a bitmap used to retrieve the screen pixels.
    delete iBitmap;
    iBitmap = 0;
    iBitmap = new (ELeave) CFbsBitmap();
	iBitmap->Create(sizeAndRotation.iPixelSize, screenDevice->DisplayMode());
    iBitmap->SetSizeInTwips(screenDevice);
    screenDevice->CopyScreenToBitmap(iBitmap);
	
	iOverlay->MakeVisible(ETrue);
    iOverlay->SetRect(TRect(TPoint(1, 1), TSize(1, 1)));
    
    CFbsBitmap* bitmap2 = new (ELeave) CFbsBitmap();
	bitmap2->Create(sizeAndRotation.iPixelSize, screenDevice->DisplayMode());
    bitmap2->SetSizeInTwips(screenDevice);
    screenDevice->CopyScreenToBitmap(bitmap2);
	TUint32* dataAddress1 = iBitmap->DataAddress();
	TUint32* dataAddress2 = bitmap2->DataAddress();
	*dataAddress1 = *dataAddress2;
    delete bitmap2;
	
	iOverlay->MakeVisible(EFalse);
	iOverlay->SetRect(TRect(TPoint(-1, -1), TSize(0, 0)));	
    }

// --------------------------------------------------------------------------
// Saves captured screenshot to a file.
// --------------------------------------------------------------------------
void CScreenShot::DoSaveL()
    {
    // Deletes the old encoder first.
    delete iImageEncoder;
    iImageEncoder = 0;

    // Gets the next available file name.
    // Although the file name will be assigned iDefaultFileName, here
    // I use local variable. The reason is that we cannot push
    // any member variables to the cleanup stack (Symbian convention).
    HBufC* fileName = GetNextFileNameLC();
    iCoeEnv.FsSession().MkDirAll(*fileName);

    // Gets the MIME type
    TPtrC8 mimeType = GetMimeType(iScreenShotData.ImageFormat());

    // Prepares the image data (if applied).
    CFrameImageData* frameImageData = CreateFrameImageDataLC(
        iScreenShotData.ImageFormat());

    // Creates a new encoder and then convert the bitmap.
    iImageEncoder = CImageEncoder::FileNewL(
        iCoeEnv.FsSession(), *fileName, mimeType);
    iImageEncoder->Convert(&iStatus, *iBitmap, frameImageData);
    CleanupStack::PopAndDestroy(); // frameImageData

    CleanupStack::Pop(); // fileName

    // Resets current file name.
    delete iCurrentFileName;
    iCurrentFileName = 0;
    iCurrentFileName = fileName;
    }

// --------------------------------------------------------------------------
// Returns MIME type based on aImageFormat.
// --------------------------------------------------------------------------
const TDesC8& CScreenShot::GetMimeType(
        CScreenShotData::TImageFormat aImageFormat)
    {
    switch (aImageFormat)
        {
        case CScreenShotData::EFormatJpgHigh:
        case CScreenShotData::EFormatJpgNormal:
        case CScreenShotData::EFormatJpgLow:
            return KMimeTypeJpg;

        case CScreenShotData::EFormatPngDefault:
        case CScreenShotData::EFormatPngSpeed:
        case CScreenShotData::EFormatPngSize:
            return KMimeTypePng;

        case CScreenShotData::EFormatBmp:
        case CScreenShotData::EFormatBmp8bpp:
            return KMimeTypeBmp;

        case CScreenShotData::EFormatMbm:
        case CScreenShotData::EFormatMbm8bpp:
            return KMimeTypeMbm;

        default:
            User::Invariant(); // panic if the format is unknown
        }

    return KMimeTypeUnknown;
    }

#if (__S60__ >= 200)

// --------------------------------------------------------------------------
// Creates frame image data based on aImageFormat.
// --------------------------------------------------------------------------
CFrameImageData* CScreenShot::CreateFrameImageDataLC(
        CScreenShotData::TImageFormat aImageFormat)
    {
    CFrameImageData* frameImageData = CFrameImageData::NewL();
    CleanupStack::PushL(frameImageData);
    switch (aImageFormat)
        {
        case CScreenShotData::EFormatJpgHigh:
        case CScreenShotData::EFormatJpgNormal:
        case CScreenShotData::EFormatJpgLow:
            {
            TJpegImageData* imageData = new (ELeave) TJpegImageData();
            imageData->iSampleScheme  = TJpegImageData::EColor444;
            if (CScreenShotData::EFormatJpgHigh == aImageFormat)
                {
                imageData->iQualityFactor = 100;
                }
            else if (CScreenShotData::EFormatJpgNormal == aImageFormat)
                {
                imageData->iQualityFactor = 90;
                }
            else if (CScreenShotData::EFormatJpgLow == aImageFormat)
                {
                imageData->iQualityFactor = 80;
                }
            User::LeaveIfError(frameImageData->AppendImageData(imageData));
            break;
            }

        case CScreenShotData::EFormatPngDefault:
        case CScreenShotData::EFormatPngSpeed:
        case CScreenShotData::EFormatPngSize:
            {
            TPngEncodeData* encodeData = new (ELeave) TPngEncodeData();
            encodeData->iPaletted     = EFalse;
            encodeData->iColor        = ETrue;
            encodeData->iBitsPerPixel = 24;
            if (CScreenShotData::EFormatPngDefault == aImageFormat)
                {
                encodeData->iLevel = TPngEncodeData::EDefaultCompression;
                }
            else if (CScreenShotData::EFormatPngSpeed == aImageFormat)
                {
                encodeData->iLevel = TPngEncodeData::EBestSpeed;
                }
            else if (CScreenShotData::EFormatPngSize == aImageFormat)
                {
                encodeData->iLevel = TPngEncodeData::EBestCompression;
                }
            User::LeaveIfError(frameImageData->AppendFrameData(encodeData));
            break;
            }

        case CScreenShotData::EFormatBmp:
            {
            TBmpImageData* imageData = new (ELeave) TBmpImageData();
            imageData->iBitsPerPixel = 24;
            User::LeaveIfError(frameImageData->AppendImageData(imageData));
            break;
            }

        case CScreenShotData::EFormatBmp8bpp:
            {
            TBmpImageData* imageData = new (ELeave) TBmpImageData();
            imageData->iBitsPerPixel = 8;
            User::LeaveIfError(frameImageData->AppendImageData(imageData));
            break;
            }

        case CScreenShotData::EFormatMbm:
            {
            TMbmEncodeData* imageData = new (ELeave) TMbmEncodeData();
            imageData->iDisplayMode = EColor16M;
            User::LeaveIfError(frameImageData->AppendFrameData(imageData));
            break;
            }

        case CScreenShotData::EFormatMbm8bpp:
            {
            TMbmEncodeData* imageData = new (ELeave) TMbmEncodeData();
            imageData->iDisplayMode = EColor256;
            User::LeaveIfError(frameImageData->AppendFrameData(imageData));
            break;
            }

        case CScreenShotData::EFormatGif:
            break;

        default:
            User::Invariant(); // panic if the format is unknown
        }
    return frameImageData;
    }

#else

// --------------------------------------------------------------------------
// Creates frame image data based on aImageFormat.
// --------------------------------------------------------------------------
CFrameImageData* CScreenShot::CreateFrameImageDataLC(
        CScreenShotData::TImageFormat aImageFormat)
    {
    CFrameImageData* frameImageData = new (ELeave) CFrameImageData();
    CleanupStack::PushL(frameImageData);
    switch (aImageFormat)
        {
        case CScreenShotData::EFormatJpgHigh:
            frameImageData->iQualityFactor = 100;
            break;

        case CScreenShotData::EFormatJpgNormal:
            frameImageData->iQualityFactor = 67;
            break;
        case CScreenShotData::EFormatJpgLow:
            frameImageData->iQualityFactor = 33;
            break;

        case CScreenShotData::EFormatPngDefault:
            frameImageData->iQualityFactor = 75;
            break;

        case CScreenShotData::EFormatPngSpeed:
            frameImageData->iQualityFactor = 100;
            break;

        case CScreenShotData::EFormatPngSize:
            frameImageData->iQualityFactor = 50;
            break;

        case CScreenShotData::EFormatBmp:
            frameImageData->iBitsPerPixel = 24;
            break;

        case CScreenShotData::EFormatBmp8bpp:
            frameImageData->iBitsPerPixel = 8;
            break;

        case CScreenShotData::EFormatGif:
            break;

        case CScreenShotData::EFormatMbm:
            frameImageData->iBitsPerPixel = 24;
            break;

        case CScreenShotData::EFormatMbm8bpp:
            frameImageData->iBitsPerPixel = 8;
            break;

        default:
            User::Invariant(); // panic if the format is unknown
        }
    return frameImageData;
    }

#endif

// --------------------------------------------------------------------------
// Fires an event. It means set this active object to active, but completes
// the request immediately.
// --------------------------------------------------------------------------
void CScreenShot::Fire(TScreenShotStatus aStatus)
    {
    iScreenShotStatus = aStatus;
    SetActive();
    TRequestStatus* status = &iStatus;
    User::RequestComplete(status, KErrNone);
    }

// --------------------------------------------------------------------------
// Fires an event after aTime microseconds.
// --------------------------------------------------------------------------
void CScreenShot::FireCapture(TTimeIntervalMicroSeconds32 aTime)
    {
    iScreenShotStatus = EWaiting;
    iTimer.After(iStatus, aTime);
    SetActive();
    }

// End of File

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?