mirror of
https://github.com/immich-app/immich.git
synced 2025-07-31 15:08:44 -04:00
draw to buffer
This commit is contained in:
parent
91a5989929
commit
a3fc5d80bb
@ -20,6 +20,8 @@ class ThumbnailApiImpl: ThumbnailApi {
|
|||||||
return requestOptions
|
return requestOptions
|
||||||
}()
|
}()
|
||||||
private static let processingQueue = DispatchQueue(label: "thumbnail.processing", qos: .userInteractive, attributes: .concurrent)
|
private static let processingQueue = DispatchQueue(label: "thumbnail.processing", qos: .userInteractive, attributes: .concurrent)
|
||||||
|
private static let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
|
||||||
|
private static let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).rawValue
|
||||||
|
|
||||||
func setThumbnailToBuffer(pointer: Int64, assetId: String, width: Int64, height: Int64, completion: @escaping (Result<Void, any Error>) -> Void) {
|
func setThumbnailToBuffer(pointer: Int64, assetId: String, width: Int64, height: Int64, completion: @escaping (Result<Void, any Error>) -> Void) {
|
||||||
guard let bufferPointer = UnsafeMutableRawPointer(bitPattern: Int(pointer))
|
guard let bufferPointer = UnsafeMutableRawPointer(bitPattern: Int(pointer))
|
||||||
@ -35,18 +37,16 @@ class ThumbnailApiImpl: ThumbnailApi {
|
|||||||
resultHandler: { (image, info) -> Void in
|
resultHandler: { (image, info) -> Void in
|
||||||
guard let image = image,
|
guard let image = image,
|
||||||
let cgImage = image.cgImage,
|
let cgImage = image.cgImage,
|
||||||
let dataProvider = cgImage.dataProvider,
|
let context = CGContext(
|
||||||
let pixelData = dataProvider.data
|
data: bufferPointer,
|
||||||
else { completion(.failure(PigeonError(code: "", message: "Could not get pixel data for \(assetId)", details: nil))); return }
|
width: cgImage.width,
|
||||||
|
height: cgImage.height,
|
||||||
guard let sourceBuffer = CFDataGetBytePtr(pixelData)
|
bitsPerComponent: 8,
|
||||||
else { completion(.failure(PigeonError(code: "", message: "Could not get pixel data buffer for \(assetId)", details: nil))); return }
|
bytesPerRow: cgImage.width * 4,
|
||||||
let dataLength = CFDataGetLength(pixelData)
|
space: Self.rgbColorSpace,
|
||||||
let bufferLength = width * height * 4
|
bitmapInfo: Self.bitmapInfo
|
||||||
guard dataLength <= bufferLength
|
) else { completion(.failure(PigeonError(code: "", message: "Could not get pixel data for \(assetId)", details: nil))); return }
|
||||||
else { completion(.failure(PigeonError(code: "", message: "Buffer is not large enough (\(bufferLength) vs \(dataLength) for \(assetId)", details: nil))); return }
|
context.draw(cgImage, in: CGRect(x: 0, y: 0, width: cgImage.width, height: cgImage.height))
|
||||||
|
|
||||||
bufferPointer.copyMemory(from: sourceBuffer, byteCount: dataLength)
|
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -92,7 +92,7 @@ class _ThumbnailState extends State<Thumbnail> {
|
|||||||
if (oldWidget.blurhash != widget.blurhash ||
|
if (oldWidget.blurhash != widget.blurhash ||
|
||||||
oldWidget.localId != widget.localId ||
|
oldWidget.localId != widget.localId ||
|
||||||
oldWidget.remoteId != widget.remoteId ||
|
oldWidget.remoteId != widget.remoteId ||
|
||||||
oldWidget.thumbhashOnly != widget.thumbhashOnly) {
|
oldWidget.thumbhashOnly && !widget.thumbhashOnly) {
|
||||||
_decode();
|
_decode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ class _ThumbnailState extends State<Thumbnail> {
|
|||||||
final blurhash = widget.blurhash;
|
final blurhash = widget.blurhash;
|
||||||
final imageFuture = thumbhashOnly ? Future.value(null) : _decodeFromFile();
|
final imageFuture = thumbhashOnly ? Future.value(null) : _decodeFromFile();
|
||||||
|
|
||||||
if (blurhash != null) {
|
if (blurhash != null && _image == null) {
|
||||||
final image = thumbhash.thumbHashToRGBA(base64.decode(blurhash));
|
final image = thumbhash.thumbHashToRGBA(base64.decode(blurhash));
|
||||||
try {
|
try {
|
||||||
await _decodeThumbhash(
|
await _decodeThumbhash(
|
||||||
|
@ -6,6 +6,7 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
|||||||
import 'package:immich_mobile/extensions/duration_extensions.dart';
|
import 'package:immich_mobile/extensions/duration_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
||||||
|
import 'package:immich_mobile/presentation/widgets/timeline/timeline.state.dart';
|
||||||
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
||||||
|
|
||||||
class ThumbnailTile extends ConsumerWidget {
|
class ThumbnailTile extends ConsumerWidget {
|
||||||
@ -38,6 +39,8 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
final isSelected = ref.watch(
|
final isSelected = ref.watch(
|
||||||
multiSelectProvider.select((multiselect) => multiselect.selectedAssets.contains(asset)),
|
multiSelectProvider.select((multiselect) => multiselect.selectedAssets.contains(asset)),
|
||||||
);
|
);
|
||||||
|
final isScrubbing =
|
||||||
|
ref.watch(timelineStateProvider.select((state) => state.isScrubbing));
|
||||||
|
|
||||||
final borderStyle = lockSelection
|
final borderStyle = lockSelection
|
||||||
? BoxDecoration(
|
? BoxDecoration(
|
||||||
@ -68,7 +71,12 @@ class ThumbnailTile extends ConsumerWidget {
|
|||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Hero(
|
child: Hero(
|
||||||
tag: '${asset?.heroTag ?? ''}_$heroIndex',
|
tag: '${asset?.heroTag ?? ''}_$heroIndex',
|
||||||
child: Thumbnail.fromBaseAsset(asset: asset, fit: fit, size: size),
|
child: Thumbnail.fromBaseAsset(
|
||||||
|
asset: asset,
|
||||||
|
fit: fit,
|
||||||
|
size: size,
|
||||||
|
thumbhashOnly: isScrubbing,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (hasStack)
|
if (hasStack)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user