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

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: address comments 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, kN32_ SkColorType, kUnpremul_SkAlphaType);
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
379 // For now, we swap R and B channel and uses kBGRA color type. 391 // Using kN32 type, swizzle input if necessary.
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, kN32_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 if (kN32_SkColorType == kBGRA_8888_SkColorType)
385 m_image = StaticBitmapImage::create(fromSkSp(SkImage::MakeRasterCopy (SkPixmap(info, srcAddr, dstPixelBytesPerRow)))); 398 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsed Options.flipY);
399 skImage = fromSkSp(SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, d stPixelBytesPerRow)));
386 // restore the original ImageData 400 // restore the original ImageData
387 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsedOpti ons.flipY); 401 if (kN32_SkColorType == kBGRA_8888_SkColorType)
402 swizzleImageData(srcAddr, srcHeight, srcPixelBytesPerRow, parsed Options.flipY);
388 } else { 403 } else {
389 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui nt8_t[dstHeight * dstPixelBytesPerRow]()); 404 std::unique_ptr<uint8_t[]> copiedDataBuffer = wrapArrayUnique(new ui nt8_t[dstHeight * dstPixelBytesPerRow]());
390 if (!srcRect.isEmpty()) { 405 if (!srcRect.isEmpty()) {
391 IntPoint srcPoint = IntPoint((parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, (parsedOptions.cropRect.y() > 0) ? parsedOptions .cropRect.y() : 0); 406 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()); 407 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(); 408 int copyHeight = srcHeight - srcPoint.y();
394 if (parsedOptions.cropRect.height() < copyHeight) 409 if (parsedOptions.cropRect.height() < copyHeight)
395 copyHeight = parsedOptions.cropRect.height(); 410 copyHeight = parsedOptions.cropRect.height();
396 int copyWidth = data->size().width() - srcPoint.x(); 411 int copyWidth = data->size().width() - srcPoint.x();
397 if (parsedOptions.cropRect.width() < copyWidth) 412 if (parsedOptions.cropRect.width() < copyWidth)
398 copyWidth = parsedOptions.cropRect.width(); 413 copyWidth = parsedOptions.cropRect.width();
399 for (int i = 0; i < copyHeight; i++) { 414 for (int i = 0; i < copyHeight; i++) {
400 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte sPerRow + srcPoint.x() * info.bytesPerPixel(); 415 int srcStartCopyPosition = (i + srcPoint.y()) * srcPixelByte sPerRow + srcPoint.x() * info.bytesPerPixel();
401 int srcEndCopyPosition = srcStartCopyPosition + copyWidth * info.bytesPerPixel(); 416 int srcEndCopyPosition = srcStartCopyPosition + copyWidth * info.bytesPerPixel();
402 int dstStartCopyPosition; 417 int dstStartCopyPosition;
403 if (parsedOptions.flipY) 418 if (parsedOptions.flipY)
404 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel(); 419 dstStartCopyPosition = (dstHeight -1 - dstPoint.y() - i) * dstPixelBytesPerRow + dstPoint.x() * info.bytesPerPixel();
405 else 420 else
406 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte sPerRow + dstPoint.x() * info.bytesPerPixel(); 421 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelByte sPerRow + dstPoint.x() * info.bytesPerPixel();
407 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio n; j++) { 422 for (int j = 0; j < srcEndCopyPosition - srcStartCopyPositio n; j++) {
408 if (j % 4 == 0) 423 // swizzle when necessary
409 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j + 2]; 424 if (kN32_SkColorType == kBGRA_8888_SkColorType) {
410 else if (j % 4 == 2) 425 if (j % 4 == 0)
411 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j - 2]; 426 copiedDataBuffer[dstStartCopyPosition + j] = src Addr[srcStartCopyPosition + j + 2];
412 else 427 else if (j % 4 == 2)
428 copiedDataBuffer[dstStartCopyPosition + j] = src Addr[srcStartCopyPosition + j - 2];
429 else
430 copiedDataBuffer[dstStartCopyPosition + j] = src Addr[srcStartCopyPosition + j];
431 } else {
413 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j]; 432 copiedDataBuffer[dstStartCopyPosition + j] = srcAddr [srcStartCopyPosition + j];
433 }
414 } 434 }
415 } 435 }
416 } 436 }
417 m_image = StaticBitmapImage::create(newSkImageFromRaster(info, std:: move(copiedDataBuffer), dstPixelBytesPerRow)); 437 skImage = newSkImageFromRaster(info, std::move(copiedDataBuffer), ds tPixelBytesPerRow);
418 } 438 }
439 if (parsedOptions.shouldScaleInput)
440 m_image = StaticBitmapImage::create(scaleSkImage(skImage, parsedOpti ons.resizeWidth, parsedOptions.resizeHeight, parsedOptions.resizeQuality));
441 else
442 m_image = StaticBitmapImage::create(skImage);
419 m_image->setPremultiplied(parsedOptions.premultiplyAlpha); 443 m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
420 return; 444 return;
421 } 445 }
422 446
423 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop Rect.size(), NonOpaque, DoNotInitializeImagePixels); 447 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(parsedOptions.crop Rect.size(), NonOpaque, DoNotInitializeImagePixels);
424 if (!buffer) 448 if (!buffer)
425 return; 449 return;
426 450
427 if (srcRect.isEmpty()) { 451 if (srcRect.isEmpty()) {
428 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 452 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown));
429 return; 453 return;
430 } 454 }
431 455
432 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std:: min(0, -parsedOptions.cropRect.y())); 456 IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()), std:: min(0, -parsedOptions.cropRect.y()));
433 if (parsedOptions.cropRect.x() < 0) 457 if (parsedOptions.cropRect.x() < 0)
434 dstPoint.setX(-parsedOptions.cropRect.x()); 458 dstPoint.setX(-parsedOptions.cropRect.x());
435 if (parsedOptions.cropRect.y() < 0) 459 if (parsedOptions.cropRect.y() < 0)
436 dstPoint.setY(-parsedOptions.cropRect.y()); 460 dstPoint.setY(-parsedOptions.cropRect.y());
437 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint); 461 buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRe ct, dstPoint);
462 RefPtr<SkImage> skImage = buffer->newSkImageSnapshot(PreferNoAcceleration, S napshotReasonUnknown);
438 if (parsedOptions.flipY) 463 if (parsedOptions.flipY)
439 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph a)); 464 skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha);
440 else 465 if (parsedOptions.shouldScaleInput) {
441 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 466 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(parsedOptions. resizeWidth, parsedOptions.resizeHeight);
467 if (!surface)
468 return;
469 SkPaint paint;
470 paint.setFilterQuality(parsedOptions.resizeQuality);
471 SkRect dstDrawRect = SkRect::MakeWH(parsedOptions.resizeWidth, parsedOpt ions.resizeHeight);
472 surface->getCanvas()->drawImageRect(skImage.get(), dstDrawRect, &paint);
473 skImage = fromSkSp(surface->makeImageSnapshot());
474 }
475 m_image = StaticBitmapImage::create(skImage);
442 } 476 }
443 477
444 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options) 478 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const ImageBitmapOptions& options)
445 { 479 {
446 RefPtr<Image> input = bitmap->bitmapImage(); 480 RefPtr<Image> input = bitmap->bitmapImage();
447 if (!input) 481 if (!input)
448 return; 482 return;
449 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ; 483 ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()) ;
450 484
451 m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); 485 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 641 FloatSize ImageBitmap::elementSize(const FloatSize&) const
608 { 642 {
609 return FloatSize(width(), height()); 643 return FloatSize(width(), height());
610 } 644 }
611 645
612 DEFINE_TRACE(ImageBitmap) 646 DEFINE_TRACE(ImageBitmap)
613 { 647 {
614 } 648 }
615 649
616 } // namespace blink 650 } // 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