本文整理汇总了C++中SkBitmap::getPixels方法的典型用法代码示例。如果您正苦于以下问题:C++ SkBitmap::getPixels方法的具体用法?C++ SkBitmap::getPixels怎么用?C++ SkBitmap::getPixels使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkBitmap
的用法示例。
在下文中一共展示了SkBitmap::getPixels方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: android_media_MediaMetadataRetriever_getFrameAtTime
static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option)
{
ALOGV("getFrameAtTime: %lld us option: %d", timeUs, option);
MediaMetadataRetriever* retriever = getRetriever(env, thiz);
if (retriever == 0) {
jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
return NULL;
}
// Call native method to retrieve a video frame
VideoFrame *videoFrame = NULL;
sp<IMemory> frameMemory = retriever->getFrameAtTime(timeUs, option);
if (frameMemory != 0) { // cast the shared structure to a VideoFrame object
videoFrame = static_cast<VideoFrame *>(frameMemory->pointer());
}
if (videoFrame == NULL) {
ALOGE("getFrameAtTime: videoFrame is a NULL pointer");
return NULL;
}
ALOGV("Dimension = %dx%d and bytes = %d",
videoFrame->mDisplayWidth,
videoFrame->mDisplayHeight,
videoFrame->mSize);
jobject config = env->CallStaticObjectMethod(
fields.configClazz,
fields.createConfigMethod,
SkBitmap::kRGB_565_Config);
size_t width, height;
bool swapWidthAndHeight = false;
if (videoFrame->mRotationAngle == 90 || videoFrame->mRotationAngle == 270) {
width = videoFrame->mHeight;
height = videoFrame->mWidth;
swapWidthAndHeight = true;
} else {
width = videoFrame->mWidth;
height = videoFrame->mHeight;
}
jobject jBitmap = env->CallStaticObjectMethod(
fields.bitmapClazz,
fields.createBitmapMethod,
width,
height,
config);
SkBitmap *bitmap =
(SkBitmap *) env->GetLongField(jBitmap, fields.nativeBitmap);
bitmap->lockPixels();
rotate((uint16_t*)bitmap->getPixels(),
(uint16_t*)((char*)videoFrame + sizeof(VideoFrame)),
videoFrame->mWidth,
videoFrame->mHeight,
videoFrame->mRotationAngle);
bitmap->unlockPixels();
if (videoFrame->mDisplayWidth != videoFrame->mWidth ||
videoFrame->mDisplayHeight != videoFrame->mHeight) {
size_t displayWidth = videoFrame->mDisplayWidth;
size_t displayHeight = videoFrame->mDisplayHeight;
if (swapWidthAndHeight) {
displayWidth = videoFrame->mDisplayHeight;
displayHeight = videoFrame->mDisplayWidth;
}
ALOGV("Bitmap dimension is scaled from %dx%d to %dx%d",
width, height, displayWidth, displayHeight);
jobject scaledBitmap = env->CallStaticObjectMethod(fields.bitmapClazz,
fields.createScaledBitmapMethod,
jBitmap,
displayWidth,
displayHeight,
true);
return scaledBitmap;
}
return jBitmap;
}
示例2:
SkPoint pt = {10 * SK_Scalar1, 10 * SK_Scalar1};
SkScalar small = 1 / (500 * SK_Scalar1);
m.mapPoints(&pt, 1);
path.addCircle(pt.fX, pt.fY, small);
canvas->drawPath(path, paint);
pt.set(30 * SK_Scalar1, 10 * SK_Scalar1);
m.mapPoints(&pt, 1);
SkRect rect = {pt.fX - small, pt.fY - small,
pt.fX + small, pt.fY + small};
canvas->drawRect(rect, paint);
SkBitmap bmp;
bmp.allocN32Pixels(2, 2);
uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels());
pixels[0] = SkPackARGB32(0xFF, 0xFF, 0x00, 0x00);
pixels[1] = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00);
pixels[2] = SkPackARGB32(0x80, 0x00, 0x00, 0x00);
pixels[3] = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF);
pt.set(30 * SK_Scalar1, 30 * SK_Scalar1);
m.mapPoints(&pt, 1);
SkMatrix s;
s.reset();
s.setScale(SK_Scalar1 / 1000, SK_Scalar1 / 1000);
SkShader* shader = SkShader::CreateBitmapShader(
bmp,
SkShader::kRepeat_TileMode,
SkShader::kRepeat_TileMode,
&s);
paint.setShader(shader)->unref();
示例3: decodeNextFrame
//.........这里部分代码省略.........
}
if (frameToDecode == fDisplayFrame.fIndex) {
if (animationEnded) {
return this->finish();
}
return fCurrentFrameDuration;
}
for (Frame* frame : { &fRestoreFrame, &fDecodingFrame }) {
if (frameToDecode == frame->fIndex) {
using std::swap;
swap(fDisplayFrame, *frame);
if (animationEnded) {
return this->finish();
}
return fCurrentFrameDuration;
}
}
// The following code makes an effort to avoid overwriting a frame that will
// be used again. If frame |i| is_restore_previous, frame |i+1| will not
// depend on frame |i|, so do not overwrite frame |i-1|, which may be needed
// for frame |i+1|.
// We could be even smarter about which frames to save by looking at the
// entire dependency chain.
SkCodec::Options options;
options.fFrameIndex = frameToDecode;
if (frameInfo.fRequiredFrame == SkCodec::kNoFrame) {
if (is_restore_previous(frameInfo.fDisposalMethod)) {
// frameToDecode will be discarded immediately after drawing, so
// do not overwrite a frame which could possibly be used in the
// future.
if (fDecodingFrame.fIndex != SkCodec::kNoFrame &&
!is_restore_previous(fDecodingFrame.fDisposalMethod)) {
using std::swap;
swap(fDecodingFrame, fRestoreFrame);
}
}
} else {
auto validPriorFrame = [&frameInfo, &frameToDecode](const Frame& frame) {
if (SkCodec::kNoFrame == frame.fIndex ||
is_restore_previous(frame.fDisposalMethod)) {
return false;
}
return frame.fIndex >= frameInfo.fRequiredFrame && frame.fIndex < frameToDecode;
};
if (validPriorFrame(fDecodingFrame)) {
if (is_restore_previous(frameInfo.fDisposalMethod)) {
// fDecodingFrame is a good frame to use for this one, but we
// don't want to overwrite it.
fDecodingFrame.copyTo(&fRestoreFrame);
}
options.fPriorFrame = fDecodingFrame.fIndex;
} else if (validPriorFrame(fDisplayFrame)) {
if (!fDisplayFrame.copyTo(&fDecodingFrame)) {
SkCodecPrintf("Failed to allocate pixels for frame\n");
return this->finish();
}
options.fPriorFrame = fDecodingFrame.fIndex;
} else if (validPriorFrame(fRestoreFrame)) {
if (!is_restore_previous(frameInfo.fDisposalMethod)) {
using std::swap;
swap(fDecodingFrame, fRestoreFrame);
} else if (!fRestoreFrame.copyTo(&fDecodingFrame)) {
SkCodecPrintf("Failed to restore frame\n");
return this->finish();
}
options.fPriorFrame = fDecodingFrame.fIndex;
}
}
auto alphaType = kOpaque_SkAlphaType == frameInfo.fAlphaType ?
kOpaque_SkAlphaType : kPremul_SkAlphaType;
auto info = fDecodeInfo.makeAlphaType(alphaType);
SkBitmap* dst = &fDecodingFrame.fBitmap;
if (!fDecodingFrame.init(info, Frame::OnInit::kRestoreIfNecessary)) {
return this->finish();
}
auto result = fCodec->codec()->getPixels(dst->info(), dst->getPixels(), dst->rowBytes(),
&options);
if (result != SkCodec::kSuccess) {
SkCodecPrintf("error %i, frame %i of %i\n", result, frameToDecode, fFrameCount);
return this->finish();
}
fDecodingFrame.fIndex = frameToDecode;
fDecodingFrame.fDisposalMethod = frameInfo.fDisposalMethod;
using std::swap;
swap(fDecodingFrame, fDisplayFrame);
fDisplayFrame.fBitmap.notifyPixelsChanged();
if (animationEnded) {
return this->finish();
}
return fCurrentFrameDuration;
}
示例4: ResizeBasic
// static
SkBitmap ImageOperations::ResizeBasic(const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
const SkIRect& dest_subset)
{
// 确保枚举值合法.
SkASSERT(((RESIZE_FIRST_QUALITY_METHOD<=method) &&
(method<=RESIZE_LAST_QUALITY_METHOD)) ||
((RESIZE_FIRST_ALGORITHM_METHOD<=method) &&
(method<=RESIZE_LAST_ALGORITHM_METHOD)));
// 用于计算函数执行时间, 方便查看是否有问题.
base::TimeTicks resize_start = base::TimeTicks::Now();
SkIRect dest = { 0, 0, dest_width, dest_height };
DCHECK(dest.contains(dest_subset)) <<
"The supplied subset does not fall within the destination image.";
// 如果源和目的大小都是0(0*0 0*N N*0), 返回一个空位图.
if(source.width()<1 || source.height()<1 ||
dest_width<1 || dest_height<1)
{
return SkBitmap();
}
method = ResizeMethodToAlgorithmMethod(method);
// Check that we deal with an "algorithm methods" from this point onward.
SkASSERT((ImageOperations::RESIZE_FIRST_ALGORITHM_METHOD<=method) &&
(method<=ImageOperations::RESIZE_LAST_ALGORITHM_METHOD));
SkAutoLockPixels locker(source);
ResizeFilter filter(method, source.width(), source.height(),
dest_width, dest_height, dest_subset);
// Get a source bitmap encompassing this touched area. We construct the
// offsets and row strides such that it looks like a new bitmap, while
// referring to the old data.
const uint8* source_subset =
reinterpret_cast<const uint8*>(source.getPixels());
// Convolve into the result.
base::CPU cpu;
SkBitmap result;
result.setConfig(SkBitmap::kARGB_8888_Config,
dest_subset.width(), dest_subset.height());
result.allocPixels();
BGRAConvolve2D(source_subset, static_cast<int>(source.rowBytes()),
!source.isOpaque(), filter.x_filter(), filter.y_filter(),
static_cast<int>(result.rowBytes()),
static_cast<unsigned char*>(result.getPixels()),
cpu.has_sse2());
// Preserve the "opaque" flag for use as an optimization later.
result.setIsOpaque(source.isOpaque());
base::TimeDelta delta = base::TimeTicks::Now() - resize_start;
UMA_HISTOGRAM_TIMES("Image.ResampleMS", delta);
return result;
}
示例5: if
//.........这里部分代码省略.........
fileBuf += sizeof(float)*boneAnim->mCount;
memcpy((float*)boneAnim->mAnimMat[0].Pointer(), fileBuf, sizeof(float)*boneAnim->mCount*16);
fileBuf += sizeof(float)*boneAnim->mCount*16;
mBoneMatData.push_back(boneAnim);
}
}
else if(gloHeader->animType == KEYFRMANIM)
{
mAnimSize = gloHeader->numAnim;
for(int anim = 0; anim < mAnimSize; anim++)
{
AnimationBin *animObj = new AnimationBin();
memcpy(animObj, fileBuf, sizeof(AnimationBin));
fileBuf += sizeof(AnimationBin);
animObj->mKeyTrans = new float[animObj->mCount*16];
memcpy(animObj->mKeyTrans, fileBuf, sizeof(float)*animObj->mCount*16);
fileBuf += sizeof(float)*animObj->mCount*16;
mAnimBinList.push_back(animObj);
}
}
else if(gloHeader->animType == NOANIMATION)
{
//cout<<"no animation found"<<endl;
}
fclose(fin);
delete[] freeBuf;
delete gloHeader;
// Load textures using skia
SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode;
SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
for(unsigned int i = 0; i < mImageList.size();i++) {
ImageTex *imgObj = mImageList.itemAt(i);
SkBitmap* bm = new SkBitmap();
if(NULL == bm) {
VR_LOGE("Skia bitmap allocation failed for scene textures\n");
}
if(SkImageDecoder::DecodeFile(imgObj->fileName, bm, prefConfig, mode, NULL))
{
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
/* load texture */
#ifdef USE_COMPRESSED_TEXTURE
SkCompressedImageRef *ref = static_cast<SkCompressedImageRef *>(bm->pixelRef());
glCompressedTexImage2D(GL_TEXTURE_2D, 0,/*GL_COMPRESSED_RGB8_ETC2*/0x9274, ref->getWidth(), ref->getHeight(), 0, ref->getPixelsByteSize(), ref->pixels());
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm->width(), bm->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)bm->getPixels());
#endif
/*load compressed texture */
imgObj->mTexId = texId;
}else {
VR_LOGE("Loading the scene texture file [%s] : failed\n", imgObj->fileName);
}
if(bm){
delete bm;
bm = 0;
}
}
for(unsigned int i = 0; i < mGeometryList.size(); i++)
{
Geometry *geom = mGeometryList.itemAt(i);
for(unsigned int j = 0; j < geom->mMeshList.size(); j++)
{
Mesh *mesh = geom->mMeshList.itemAt(j);
ImageTex *imgObj = mImageList.itemAt(mesh->mImgObjIndex);
mesh->mTexId= imgObj->mTexId;
imgObj = 0;
}
geom = 0;
}
return true;
}
示例6: generateMask
static void generateMask(const SkMask& mask, const SkPath& path,
const SkMaskGamma::PreBlend& maskPreBlend) {
SkPaint paint;
int srcW = mask.fBounds.width();
int srcH = mask.fBounds.height();
int dstW = srcW;
int dstH = srcH;
int dstRB = mask.fRowBytes;
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
SkBitmap::Config config = SkBitmap::kA8_Config;
paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
switch (mask.fFormat) {
case SkMask::kBW_Format:
dstRB = 0; // signals we need a copy
break;
case SkMask::kA8_Format:
break;
case SkMask::kLCD16_Format:
case SkMask::kLCD32_Format:
// TODO: trigger off LCD orientation
dstW = 4*dstW - 8;
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
-SkIntToScalar(mask.fBounds.fTop));
matrix.postScale(SkIntToScalar(4), SK_Scalar1);
dstRB = 0; // signals we need a copy
break;
default:
SkDEBUGFAIL("unexpected mask format");
}
SkRasterClip clip;
clip.setRect(SkIRect::MakeWH(dstW, dstH));
SkBitmap bm;
bm.setConfig(config, dstW, dstH, dstRB);
if (0 == dstRB) {
if (!bm.allocPixels()) {
// can't allocate offscreen, so empty the mask and return
sk_bzero(mask.fImage, mask.computeImageSize());
return;
}
bm.lockPixels();
} else {
bm.setPixels(mask.fImage);
}
sk_bzero(bm.getPixels(), bm.getSafeSize());
SkDraw draw;
draw.fRC = &clip;
draw.fClip = &clip.bwRgn();
draw.fMatrix = &matrix;
draw.fBitmap = &bm;
draw.drawPath(path, paint);
switch (mask.fFormat) {
case SkMask::kBW_Format:
packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
break;
case SkMask::kA8_Format:
if (maskPreBlend.isApplicable()) {
applyLUTToA8Mask(mask, maskPreBlend.fG);
}
break;
case SkMask::kLCD16_Format:
if (maskPreBlend.isApplicable()) {
pack4xHToLCD16<true>(bm, mask, maskPreBlend);
} else {
pack4xHToLCD16<false>(bm, mask, maskPreBlend);
}
break;
case SkMask::kLCD32_Format:
if (maskPreBlend.isApplicable()) {
pack4xHToLCD32<true>(bm, mask, maskPreBlend);
} else {
pack4xHToLCD32<false>(bm, mask, maskPreBlend);
}
break;
default:
break;
}
}
示例7: check
static void check(skiatest::Reporter* r,
const char path[],
SkISize size,
bool supportsScanlineDecoding,
bool supportsSubsetDecoding) {
SkAutoTDelete<SkStream> stream(resource(path));
if (!stream) {
SkDebugf("Missing resource '%s'\n", path);
return;
}
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
if (!codec) {
ERRORF(r, "Unable to decode '%s'", path);
return;
}
// This test is used primarily to verify rewinding works properly. Using kN32 allows
// us to test this without the added overhead of creating different bitmaps depending
// on the color type (ex: building a color table for kIndex8). DM is where we test
// decodes to all possible destination color types.
SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
REPORTER_ASSERT(r, info.dimensions() == size);
SkBitmap bm;
bm.allocPixels(info);
SkAutoLockPixels autoLockPixels(bm);
SkCodec::Result result =
codec->getPixels(info, bm.getPixels(), bm.rowBytes(), NULL, NULL, NULL);
REPORTER_ASSERT(r, result == SkCodec::kSuccess);
SkMD5::Digest digest;
md5(bm, &digest);
bm.eraseColor(SK_ColorYELLOW);
result =
codec->getPixels(info, bm.getPixels(), bm.rowBytes(), NULL, NULL, NULL);
REPORTER_ASSERT(r, result == SkCodec::kSuccess);
// verify that re-decoding gives the same result.
compare_to_good_digest(r, digest, bm);
stream.reset(resource(path));
SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(
SkScanlineDecoder::NewFromStream(stream.detach()));
if (supportsScanlineDecoding) {
bm.eraseColor(SK_ColorYELLOW);
REPORTER_ASSERT(r, scanlineDecoder);
REPORTER_ASSERT(r, scanlineDecoder->start(info) == SkCodec::kSuccess);
for (int y = 0; y < info.height(); y++) {
result = scanlineDecoder->getScanlines(bm.getAddr(0, y), 1, 0);
REPORTER_ASSERT(r, result == SkCodec::kSuccess);
}
// verify that scanline decoding gives the same result.
compare_to_good_digest(r, digest, bm);
} else {
REPORTER_ASSERT(r, !scanlineDecoder);
}
// The rest of this function tests decoding subsets, and will decode an arbitrary number of
// random subsets.
// Do not attempt to decode subsets of an image of only once pixel, since there is no
// meaningful subset.
if (size.width() * size.height() == 1) {
return;
}
SkRandom rand;
SkIRect subset;
SkCodec::Options opts;
opts.fSubset = ⊂
for (int i = 0; i < 5; i++) {
subset = generate_random_subset(&rand, size.width(), size.height());
SkASSERT(!subset.isEmpty());
const bool supported = codec->getValidSubset(&subset);
REPORTER_ASSERT(r, supported == supportsSubsetDecoding);
SkImageInfo subsetInfo = info.makeWH(subset.width(), subset.height());
SkBitmap bm;
bm.allocPixels(subsetInfo);
const SkCodec::Result result = codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes(),
&opts, NULL, NULL);
if (supportsSubsetDecoding) {
REPORTER_ASSERT(r, result == SkCodec::kSuccess);
// Webp is the only codec that supports subsets, and it will have modified the subset
// to have even left/top.
REPORTER_ASSERT(r, SkIsAlign2(subset.fLeft) && SkIsAlign2(subset.fTop));
} else {
// No subsets will work.
REPORTER_ASSERT(r, result == SkCodec::kUnimplemented);
}
}
}
示例8: initTexture
status_t BootAnimation::initTexture(void* buffer, size_t len)
{
//StopWatch watch("blah");
SkBitmap bitmap;
SkMemoryStream stream(buffer, len);
SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
if (codec) {
codec->setDitherImage(false);
codec->decode(&stream, &bitmap,
SkBitmap::kARGB_8888_Config,
SkImageDecoder::kDecodePixels_Mode);
delete codec;
}
// ensure we can call getPixels(). No need to call unlock, since the
// bitmap will go out of scope when we return from this method.
bitmap.lockPixels();
const int w = bitmap.width();
const int h = bitmap.height();
const void* p = bitmap.getPixels();
GLint crop[4] = { 0, h, w, -h };
int tw = 1 << (31 - __builtin_clz(w));
int th = 1 << (31 - __builtin_clz(h));
if (tw < w) tw <<= 1;
if (th < h) th <<= 1;
switch (bitmap.getConfig()) {
case SkBitmap::kARGB_8888_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, p);
}
break;
case SkBitmap::kRGB_565_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, p);
}
break;
default:
break;
}
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
return NO_ERROR;
}
示例9: filterImageGeneric
bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc procX,
SkMorphologyImageFilter::Proc procY,
Proxy* proxy,
const SkBitmap& source,
const Context& ctx,
SkBitmap* dst,
SkIPoint* offset) const {
SkBitmap src = source;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) {
return false;
}
if (src.colorType() != kN32_SkColorType) {
return false;
}
SkIRect bounds;
if (!this->applyCropRect(this->mapContext(ctx), proxy, src, &srcOffset, &bounds, &src)) {
return false;
}
SkAutoLockPixels alp(src);
if (!src.getPixels()) {
return false;
}
SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
SkIntToScalar(this->radius().height()));
ctx.ctm().mapVectors(&radius, 1);
int width = SkScalarFloorToInt(radius.fX);
int height = SkScalarFloorToInt(radius.fY);
if (width < 0 || height < 0) {
return false;
}
SkIRect srcBounds = bounds;
srcBounds.offset(-srcOffset);
if (width == 0 && height == 0) {
src.extractSubset(dst, srcBounds);
offset->fX = bounds.left();
offset->fY = bounds.top();
return true;
}
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
if (!device) {
return false;
}
*dst = device->accessBitmap(false);
SkAutoLockPixels alp_dst(*dst);
if (width > 0 && height > 0) {
SkAutoTUnref<SkBaseDevice> tempDevice(proxy->createDevice(dst->width(), dst->height()));
if (!tempDevice) {
return false;
}
SkBitmap temp = tempDevice->accessBitmap(false);
SkAutoLockPixels alp_temp(temp);
callProcX(procX, src, &temp, width, srcBounds);
SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height());
callProcY(procY, temp, dst, height, tmpBounds);
} else if (width > 0) {
callProcX(procX, src, dst, width, srcBounds);
} else if (height > 0) {
callProcY(procY, src, dst, height, srcBounds);
}
offset->fX = bounds.left();
offset->fY = bounds.top();
return true;
}
示例10: bitmap_to_pdf_pixels
static void bitmap_to_pdf_pixels(const SkBitmap& bitmap, SkWStream* out) {
if (!bitmap.getPixels()) {
size_t size = pixel_count(bitmap) *
pdf_color_component_count(bitmap.colorType());
fill_stream(out, '\x00', size);
return;
}
SkBitmap copy;
const SkBitmap& bm = not4444(bitmap, ©);
SkAutoLockPixels autoLockPixels(bm);
switch (bm.colorType()) {
case kN32_SkColorType: {
SkASSERT(3 == pdf_color_component_count(bitmap.colorType()));
SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
for (int y = 0; y < bm.height(); ++y) {
const SkPMColor* src = bm.getAddr32(0, y);
uint8_t* dst = scanline.get();
for (int x = 0; x < bm.width(); ++x) {
SkPMColor color = *src++;
U8CPU alpha = SkGetPackedA32(color);
if (alpha != SK_AlphaTRANSPARENT) {
pmcolor_to_rgb24(color, dst);
} else {
get_neighbor_avg_color(bm, x, y, dst);
}
dst += 3;
}
out->write(scanline.get(), 3 * bm.width());
}
return;
}
case kRGB_565_SkColorType: {
SkASSERT(3 == pdf_color_component_count(bitmap.colorType()));
SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
for (int y = 0; y < bm.height(); ++y) {
const uint16_t* src = bm.getAddr16(0, y);
uint8_t* dst = scanline.get();
for (int x = 0; x < bm.width(); ++x) {
U16CPU color565 = *src++;
*dst++ = SkPacked16ToR32(color565);
*dst++ = SkPacked16ToG32(color565);
*dst++ = SkPacked16ToB32(color565);
}
out->write(scanline.get(), 3 * bm.width());
}
return;
}
case kAlpha_8_SkColorType:
SkASSERT(1 == pdf_color_component_count(bitmap.colorType()));
fill_stream(out, '\x00', pixel_count(bm));
return;
case kGray_8_SkColorType:
case kIndex_8_SkColorType:
SkASSERT(1 == pdf_color_component_count(bitmap.colorType()));
// these two formats need no transformation to serialize.
for (int y = 0; y < bm.height(); ++y) {
out->write(bm.getAddr8(0, y), bm.width());
}
return;
case kUnknown_SkColorType:
case kARGB_4444_SkColorType:
default:
SkDEBUGFAIL("unexpected color type");
}
}
示例11: encode
bool PNGImageEncoder::encode(const SkBitmap& bitmap, Vector<unsigned char>* output)
{
SkAutoLockPixels bitmapLock(bitmap);
if (bitmap.config() != SkBitmap::kARGB_8888_Config)
return false; // Only support 32 bit/pixel skia bitmaps.
return encodePixels(IntSize(bitmap.width(), bitmap.height()), static_cast<unsigned char*>(bitmap.getPixels()), true, output);
}
示例12: processHQRequest
/*
* High quality is implemented by performing up-right scale-only filtering and then
* using bilerp for any remaining transformations.
*/
bool SkDefaultBitmapControllerState::processHQRequest(const SkBitmapProvider& provider) {
if (fQuality != kHigh_SkFilterQuality) {
return false;
}
// Our default return state is to downgrade the request to Medium, w/ or w/o setting fBitmap
// to a valid bitmap. If we succeed, we will set this to Low instead.
fQuality = kMedium_SkFilterQuality;
if (kN32_SkColorType != provider.info().colorType() || !cache_size_okay(provider, fInvMatrix) ||
fInvMatrix.hasPerspective())
{
return false; // can't handle the reqeust
}
SkScalar invScaleX = fInvMatrix.getScaleX();
SkScalar invScaleY = fInvMatrix.getScaleY();
if (fInvMatrix.getType() & SkMatrix::kAffine_Mask) {
SkSize scale;
if (!fInvMatrix.decomposeScale(&scale)) {
return false;
}
invScaleX = scale.width();
invScaleY = scale.height();
}
if (SkScalarNearlyEqual(invScaleX, 1) && SkScalarNearlyEqual(invScaleY, 1)) {
return false; // no need for HQ
}
#ifndef SK_SUPPORT_LEGACY_HQ_DOWNSAMPLING
if (invScaleX > 1 || invScaleY > 1) {
return false; // only use HQ when upsampling
}
#endif
const int dstW = SkScalarRoundToScalar(provider.width() / invScaleX);
const int dstH = SkScalarRoundToScalar(provider.height() / invScaleY);
const SkBitmapCacheDesc desc = provider.makeCacheDesc(dstW, dstH);
if (!SkBitmapCache::FindWH(desc, &fResultBitmap)) {
SkBitmap orig;
if (!provider.asBitmap(&orig)) {
return false;
}
SkAutoPixmapUnlock src;
if (!orig.requestLock(&src)) {
return false;
}
if (!SkBitmapScaler::Resize(&fResultBitmap, src.pixmap(), kHQ_RESIZE_METHOD,
dstW, dstH, SkResourceCache::GetAllocator())) {
return false; // we failed to create fScaledBitmap
}
SkASSERT(fResultBitmap.getPixels());
fResultBitmap.setImmutable();
if (!provider.isVolatile()) {
if (SkBitmapCache::AddWH(desc, fResultBitmap)) {
provider.notifyAddedToCache();
}
}
}
SkASSERT(fResultBitmap.getPixels());
fInvMatrix.postScale(SkIntToScalar(dstW) / provider.width(),
SkIntToScalar(dstH) / provider.height());
fQuality = kLow_SkFilterQuality;
return true;
}