2011-01-27 11 views
18

Tôi đang làm việc trên một ứng dụng xử lý hình ảnh cho Android, công nhận ký hiệu âm nhạc từ các hình ảnh được lấy từ các bản nhạc.Có thể cắt một bitmap thành các mẩu nhỏ mà không tải toàn bộ nội dung vào bộ nhớ không?

Tôi đã cố gắng tải toàn bộ hình ảnh vào một Bitmap bằng phương pháp BitmapFactory.decodeFile(imgPath), nhưng vì điện thoại của tôi không có đủ bộ nhớ, tôi nhận được lỗi "Kích thước đống máy ảo". Để giải quyết vấn đề này, tôi muốn cắt hình ảnh đầy đủ thành những phần nhỏ hơn, nhưng tôi không chắc chắn làm thế nào để làm điều đó.

Tôi cũng thấy rằng có thể giảm kích thước bộ nhớ của Bitmap bằng cách sử dụng inSampleSize property của lớp BitmapFactory.Option, nhưng nếu tôi làm điều đó tôi sẽ không nhận được hình ảnh có độ phân giải cao mà tôi cần cho ký hiệu âm nhạc quá trình nhận diện.

Có cách nào để xử lý việc này mà không cần đến NDK không?

+0

là tập tin của bạn thực sự mã hóa như một bitmap? Bạn có thể nén hình ảnh nguồn để nó không lớn không? Đối với âm nhạc, bạn không cần nhiều màu sắc ... Làm thế nào lớn trong byte và độ phân giải là những hình ảnh bạn đang làm việc với? – Matt

+0

Bản đồ bitmap của bạn hay của người dùng? Nếu của bạn, hãy xem xét lưu trữ nó trước khi cắt nhỏ lên, và/hoặc trong ít màu sắc. Nếu người dùng, đây có phải là trường hợp đường biên hoặc đầu vào điển hình không? Nếu đường biên giới, thực hiện xác thực/xử lý lỗi duyên dáng. Nếu điển hình, hãy xem xét lại lựa chọn nền tảng của bạn. –

+0

Bitmap là từ người dùng. Anh ấy sẽ chụp ảnh từ camera di động. Tôi phải sử dụng bitmap lớn nhất có thể bởi vì trong quá trình nhận biết hiệu quả là từ việc này. Cảm ơn bạn đã chỉnh sửa và xin lỗi vì tiếng Anh nghèo nàn của tôi. – OffCS

Trả lời

1

Nếu từ máy ảnh, hình ảnh có thể có định dạng jpeg. Bạn có thể sử dụng một thư viện jpeg bên ngoài - hoặc trong java hoặc thông qua NDK, bất cứ điều gì bạn có thể tìm thấy - để cung cấp cho bạn kiểm soát tốt hơn và tải nó một mảnh tại một thời điểm. Nếu bạn cần nó như là một android.graphics.Bitmap thì tôi nghi ngờ bạn sẽ cần phải mã hóa lại subimage dưới dạng PNG hoặc JPEG và chuyển nó sang BitmapFactory.decodeByteArray(). (Nếu bộ nhớ là mối quan ngại thì hãy nhớ quên tham chiếu của bạn tới các phần của bitmap ngay để bộ thu gom rác có thể chạy hiệu quả.)

Kỹ thuật tương tự cũng sẽ hoạt động nếu đồ họa đầu vào là định dạng PNG hoặc chỉ là về bất cứ điều gì khác được cung cấp, bạn có thể tìm mã giải mã phù hợp cho nó.

Tôi nghĩ rằng bằng cách tải hình ảnh, bạn sẽ đặt cho mình một thách thức về thuật toán trong việc quyết định những phần nào của nó mà bạn thực sự quan tâm đến đầy đủ chi tiết. Tôi nhận thấy rằng BitmapFactory.Options bao gồm tùy chọn để mẫu phụ, điều đó có thể hữu ích nếu bạn muốn phân tích tổng quan về hình ảnh để quyết định vùng nào sẽ tải đầy đủ chi tiết.

1

Nếu bạn đang xử lý ảnh JPEG, hãy xem câu trả lời của tôi cho this question cũng như this example.

Tôi không biết làm thế nào có thể để có được libijg trên Android, nhưng nếu có, sau đó nó có giá trị một shot.

27

Android 2.3.3 có API mới có tên android.graphics.BitmapRegionDecoder cho phép bạn thực hiện chính xác những gì bạn muốn.

Bạn sẽ ví dụ làm như sau:

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false); 
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null); 

dễ dàng :)

+0

Lớp này là ở 2.3.3 và điều này là tốt nếu bạn đồng ý với ứng dụng của mình chỉ hoạt động trên 2,3 .3 trở lên, nhưng những gì về các phiên bản trước? –

+3

Bạn có thể lấy mã từ kho git và sử dụng nó trong ứng dụng của bạn :) –

+0

@RomainGuy, bạn có thể xây dựng một chút về cách thực hiện điều đó không? Có vẻ như mã này tham chiếu đến các phương thức nguyên gốc .. chúng ta cũng cần lấy các phương thức gốc đó từ git, và biên dịch với NDK, hay là lớp java đầy đủ trên chính nó? – snapfractalpop