Miałem trudności ze znalezieniem najlepszych praktyk, a nawet porad, aby rozwiązać mój problem. Opierając się na this anwer by JannGabriel, który przycina obraz prawym i dolnym zmniejszając rozmiar obrazu, udało mi się zrobić krok dalej, a także usunąć górne i lewe spacje i ogólnie poprawić czas opracowania. Wynik jest dobry i obecnie używam go w moim projekcie. Jestem całkiem nowy w programowaniu Androida i wszelkie rady dotyczące tej metody są mile widziane.
public static Bitmap TrimBitmap(Bitmap bmp) {
int imgHeight = bmp.getHeight();
int imgWidth = bmp.getWidth();
//TRIM WIDTH - LEFT
int startWidth = 0;
for(int x = 0; x < imgWidth; x++) {
if (startWidth == 0) {
for (int y = 0; y < imgHeight; y++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
startWidth = x;
break;
}
}
} else break;
}
//TRIM WIDTH - RIGHT
int endWidth = 0;
for(int x = imgWidth - 1; x >= 0; x--) {
if (endWidth == 0) {
for (int y = 0; y < imgHeight; y++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
endWidth = x;
break;
}
}
} else break;
}
//TRIM HEIGHT - TOP
int startHeight = 0;
for(int y = 0; y < imgHeight; y++) {
if (startHeight == 0) {
for (int x = 0; x < imgWidth; x++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
startHeight = y;
break;
}
}
} else break;
}
//TRIM HEIGHT - BOTTOM
int endHeight = 0;
for(int y = imgHeight - 1; y >= 0; y--) {
if (endHeight == 0) {
for (int x = 0; x < imgWidth; x++) {
if (bmp.getPixel(x, y) != Color.TRANSPARENT) {
endHeight = y;
break;
}
}
} else break;
}
return Bitmap.createBitmap(
bmp,
startWidth,
startHeight,
endWidth - startWidth,
endHeight - startHeight
);
}
Objaśnienie: Dla każdej strony obrazu, pętli FOR jest uruchamiany w celu sprawdzenia, czy nie zawiera piksele nie kolor przezroczysty, wracając pierwszy nieprzejrzyste pikseli przydatna współrzędnych. W tym celu opracowujemy współrzędne, używając jako podstawy wymiaru przeciwnego niż wymiar do przycięcia: aby znaleźć y, zeskanuj x dla każdego y.
Aby sprawdzić, gdzie kończy się pionowe Top spacja, uruchamia następujące czynności:
- początkowa wynosi od górnego rzędu (y = 0)
- Sprawdza wszystkie kolumny z rzędu (x od 0 do imageWidth)
- Jeśli zostanie znaleziony nieprzezroczysty piksel, przerwij pętlę i zapisz współrzędną y. W przeciwnym razie kontynuuj.
- Po zakończeniu kolumn przejdź do następnego wiersza (y + 1) i rozpocznij sprawdzanie kolumn. Przerwij, jeśli nieprzejrzysty piksel został już znaleziony.
Podobne metody są stosowane dla innych wymiarów, zmieniając tylko kierunek skanowania.
Po uzyskał 4 współrzędne pierwszych przydatnych pikseli obrazu, metoda Bitmap.createBitmap
jest wywoływana z oryginalnej bitmapy jako obrazu bazowego, a użyteczne pikseli współrzędne jako lewego górnego i prawego dolnego limitów dla zmiany rozmiaru .
Uwaga 1: Warto pamiętać, że współrzędne 0, 0 jest równa lewy górny.
Uwaga 2: Końcowa szerokość i wysokość w Bitmap.createBitmap są zmniejszane o nową początkową współrzędną względną, w przeciwnym razie nowy obraz będzie nieprawidłowo przesuwać granice w prawym dolnym rogu. Wyobraź sobie: masz obraz 100x100px, więc z końcowymi współrzędnymi 100, 100. Zmiana współrzędnych początkowych na 50,50 spowoduje, że końcowe współrzędne prostokąta opracowania wynoszą 150 150 (100 oryginalnych współrzędnych + 50 zmodyfikowanych punktów początkowych), przesuwając je poza oryginalne obramowania obrazu. Aby tego uniknąć, nowa współrzędna końcowa jest zmniejszana o nową współrzędną początkową (100 + 50 nowych początkowych współrzędnych - 50 nowych początkowych korekt współrzędnych)
Uwaga 3: w oryginalnej odpowiedzi zaznaczenie wszystkich pikseli w danym kierunek jest uruchamiany przy użyciu tego samego wymiaru współrzędnej, aby znaleźć, zwracając najbardziej zaawansowany użyteczny piksel.Sprawdzenie przeciwnego wymiaru i zatrzymanie przy pierwszym użytecznym pikselu zwiększyło wydajność.
Twój przykładowy kod będzie przycinać przynajmniej jeden piksel, nawet jeśli obraz ma przejrzystą kolumny lub wiersza. Lepiej jest użyć sposobu opisanego w 'http: // stackoverflow.com/a/886979/1043882' zamiast' if (startWidth == 0) 'i innych podobnych wypowiedzi. – hasanghaforian
'' startHeight' startWidth' i nie powinien być ustawiony na 0 na początku, bo jeśli obraz nie ma pustej przestrzeni na górze i po lewej stronie Twojego for-pętle potrwa do końca. Więc tracisz czas obliczeniowy równy "2 * szerokości * wysokości". Myślę, że lepiej ustawić je na "-1". – Ruslan