Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(629)

Side by Side Diff: third_party/WebKit/Source/core/frame/ImageBitmap.cpp

Issue 2183323003: Implement resize option for createImageBitmap from ImageData (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-resize.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/ImageBitmap.h" 5 #include "core/frame/ImageBitmap.h"
6 6
7 #include "core/html/HTMLCanvasElement.h" 7 #include "core/html/HTMLCanvasElement.h"
8 #include "core/html/HTMLVideoElement.h" 8 #include "core/html/HTMLVideoElement.h"
9 #include "core/html/ImageData.h" 9 #include "core/html/ImageData.h"
10 #include "platform/graphics/skia/SkiaUtils.h" 10 #include "platform/graphics/skia/SkiaUtils.h"
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 } 356 }
357 357
358 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32 _t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean) 358 ImageBitmap::ImageBitmap(std::unique_ptr<uint8_t[]> data, uint32_t width, uint32 _t height, bool isImageBitmapPremultiplied, bool isImageBitmapOriginClean)
359 { 359 {
360 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); 360 SkImageInfo info = SkImageInfo::MakeN32(width, height, isImageBitmapPremulti plied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
361 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma p(info, data.get(), info.bytesPerPixel() * width)))); 361 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy(SkPixma p(info, data.get(), info.bytesPerPixel() * width))));
362 m_image->setPremultiplied(isImageBitmapPremultiplied); 362 m_image->setPremultiplied(isImageBitmapPremultiplied);
363 m_image->setOriginClean(isImageBitmapOriginClean); 363 m_image->setOriginClean(isImageBitmapOriginClean);
364 } 364 }
365 365
366 static PassRefPtr<SkImage> scaleSkImage(PassRefPtr<SkImage> skImage, unsigned re sizeWidth, unsigned resizeHeight, SkFilterQuality resizeQuality)
367 {
368 SkImageInfo resizedInfo = SkImageInfo::Make(resizeWidth, resizeHeight, kBGRA _8888_SkColorType, kUnpremul_SkAlphaType);
Justin Novosad 2016/07/27 17:05:05 Why BGRA instead of N32 (the platform-specific def
xidachen 2016/07/28 13:21:16 Done, changed to N32. Swizzle is applied only when
369 std::unique_ptr<uint8_t[]> resizedPixels = wrapArrayUnique(new uint8_t[resiz eWidth * resizeHeight * resizedInfo.bytesPerPixel()]);
370 SkPixmap pixmap(resizedInfo, resizedPixels.release(), resizeWidth * resizedI nfo.bytesPerPixel());
371 skImage->scalePixels(pixmap, resizeQuality);
372 return fromSkSp(SkImage::MakeFromRaster(pixmap, [](const void* pixels, void* )
373 {
374 delete[] static_cast<const uint8_t*>(pixels);
375 }, nullptr));
376 }
377
366 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag eBitmapOptions& options) 378 ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag eBitmapOptions& options)
367 { 379 {
368 // TODO(xidachen): implement the resize option 380 // TODO(xidachen): implement the resize option
369 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); 381 IntRect dataSrcRect = IntRect(IntPoint(), data->size());
370 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo urceSize()); 382 ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSo urceSize());
371 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec t) : dataSrcRect; 383 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRec t) : dataSrcRect;
372 384
373 // treat non-premultiplyAlpha as a special case 385 // treat non-premultiplyAlpha as a special case
374 if (!parsedOptions.premultiplyAlpha) { 386 if (!parsedOptions.premultiplyAlpha) {
375 unsigned char* srcAddr = data->data()->data(); 387 unsigned char* srcAddr = data->data()->data();
376 int srcHeight = data->size().height(); 388 int srcHeight = data->size().height();
377 int dstHeight = parsedOptions.cropRect.height(); 389 int dstHeight = parsedOptions.cropRect.height();
378 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k RGBA color type. 390 // TODO (xidachen): skia doesn't support SkImage::NewRasterCopy from a k RGBA color type.
379 // For now, we swap R and B channel and uses kBGRA color type. 391 // For now, we swap R and B channel and uses kBGRA color type.
380 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dst Height, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); 392 SkImageInfo info = SkImageInfo::Make(parsedOptions.cropRect.width(), dst Height, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType);
381 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width(); 393 int srcPixelBytesPerRow = info.bytesPerPixel() * data->size().width();
382 int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect. width(); 394 int dstPixelBytesPerRow = info.bytesPerPixel() * parsedOptions.cropRect. width();
395 RefPtr<SkImage> skImage;
383 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { 396 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) {
384 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY); 397 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY);
385 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy (SkPixmap(info, srcAddr, dstPixelBytesPerRow)))); 398 skImage = fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, d stPixelBytesPerRow)));
Justin Novosad 2016/07/27 17:05:05 It's a shame to have to make an make a copy here t
xidachen 2016/07/28 13:21:16 Not easy. SkSurface doesn't support un-premultipli
386 // restore the original ImageData 399 // restore the original ImageData
387 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY); 400 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY);
388 } else { 401 } else {
389 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui nt8_t[dstHeight * dstPixelBytesPerRow]()); 402 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui nt8_t[dstHeight * dstPixelBytesPerRow]());
390 if (!srcRect.isEmpty()) { 403 if (!srcRect.isEmpty()) {
391 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions .cropRect.y() : 0); 404 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions .cropRect.y() : 0);
392 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse dOptions.cropRect.y()); 405 IntPoint dstPoint = IntPoint((parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), (parsedOptions.cropRect.y() >= 0) ? 0 : -parse dOptions.cropRect.y());
393 int copyHeight = srcHeight - srcPoint.y(); 406 int copyHeight = srcHeight - srcPoint.y();
394 if (parsedOptions.cropRect.height() < copyHeight) 407 if (parsedOptions.cropRect.height() < copyHeight)
395 copyHeight = parsedOptions.cropRect.height(); 408 copyHeight = parsedOptions.cropRect.height();
(...skipping 11 matching lines...) Expand all
407 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio n; j++) { 420 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio n; j++) {
408 if (j % 4 == 0) 421 if (j % 4 == 0)
409 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j + 2]; 422 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j + 2];
410 else if (j % 4 == 2) 423 else if (j % 4 == 2)
411 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j - 2]; 424 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j - 2];
412 else 425 else
413 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j]; 426 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j];
414 } 427 }
415 } 428 }
416 } 429 }
417 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std:: move(copiedDataBuffer), dstPixelBytesPerRow)); 430 skImage = newSkImageFromRaster(info, std::move(copiedDataBuffer), ds tPixelBytesPerRow);
418 } 431 }
432 if (parsedOptions.shouldScaleInput)
433 m_image = StaticBitmapImage::create(scaleSkImage(skImage, parsedOpti ons.resizeWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality));
434 else
435 m_image = StaticBitmapImage::create(skImage);
419 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); 436 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
420 return; 437 return;
421 } 438 }
422 439
423 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop Rect.size(), NonOpaque, DoNotInitializeImagePixels); 440 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop Rect.size(), NonOpaque, DoNotInitializeImagePixels);
424 if (!buffer) 441 if (!buffer)
425 return; 442 return;
426 443
427 if (srcRect.isEmpty()) { 444 if (srcRect.isEmpty()) {
428 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 445 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown));
429 return; 446 return;
430 } 447 }
431 448
432 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std:: min(0, -parsedOptions.cropRect.y())); 449 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std:: min(0, -parsedOptions.cropRect.y()));
433 if (parsedOptions.cropRect.x() < 0) 450 if (parsedOptions.cropRect.x() < 0)
434 dstPoint.setX(-parsedOptions.cropRect.x()); 451 dstPoint.setX(-parsedOptions.cropRect.x());
435 if (parsedOptions.cropRect.y() < 0) 452 if (parsedOptions.cropRect.y() < 0)
436 dstPoint.setY(-parsedOptions.cropRect.y()); 453 dstPoint.setY(-parsedOptions.cropRect.y());
437 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint); 454 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint);
455 RefPtr<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, S napshotReasonUnknown);
438 if (parsedOptions.flipY) 456 if (parsedOptions.flipY)
439 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph a)); 457 skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha);
440 else 458 if (parsedOptions.shouldScaleInput) {
441 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 459 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions. resizeWidth, parsedOptions.resizeHeight);
460 if (!surface)
461 return;
462 SkPaint paint;
463 paint.setFilterQuality(parsedOptions.resizeQuality);
464 SkRect dstDrawRect = SkRect::MakeWH(parsedOptions.resizeWidth, parsedOpt ions.resizeHeight);
465 surface->getCanvas()->drawImageRect(skImage.get(), dstDrawRect, &paint);
466 skImage = fromSkSp(surface->makeImageSnapshot());
467 }
468 m_image = StaticBitmapImage::create(skImage);
442 } 469 }
443 470
444 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options) 471 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
445 { 472 {
446 RefPtr<Image> input = bitmap->bitmapImage(); 473 RefPtr<Image> input = bitmap->bitmapImage();
447 if (!input) 474 if (!input)
448 return; 475 return;
449 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ; 476 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ;
450 477
451 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); 478 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 FloatSize ImageBitmap::elementSize(const FloatSize&) const 634 FloatSize ImageBitmap::elementSize(const FloatSize&) const
608 { 635 {
609 return FloatSize(width(), height()); 636 return FloatSize(width(), height());
610 } 637 }
611 638
612 DEFINE_TRACE(ImageBitmap) 639 DEFINE_TRACE(ImageBitmap)
613 { 640 {
614 } 641 }
615 642
616 } // namespace blink 643 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-resize.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698